Java: Reflection, Generic Types, and Unchecked Casts -
my class given object class. using reflection iterate on declared fields of class , registering changelistener
on each field property
base class.
the original 'createchangelistener' method looked this:
private void createchangelistener(property property) { property.addlistener(new changelistener() { @override public void changed(observablevalue observable, object oldvalue, object newvalue) { foo.this.propertychanged(observable); } }); }
however, producing unwanted warning:
warning: [unchecked] unchecked call addlistener(changelistener<? super t>) member of raw type observablevalue property.addlistener(new changelistener() { t type-variable: t extends object declared in interface observablevalue
not dissuaded, provided generic type property
parameter , changelistener
:
private void createchangelistener(property<object> property) { property.addlistener(new changelistener<object>() { @override public void changed(observablevalue observable, object oldvalue, object newvalue) { foo.this.propertychanged(observable); } }); }
...only notified have shifted problem source of reflection. code, below, modified cast property<object>
original property
w/o generic type:
if (property.class.isassignablefrom(field.gettype())) { createchangelistener((property<object>)(field.get(model))); }
this warningless code producing head-tilting:
warning: [unchecked] unchecked cast createchangelistener((property<object>)(field.get(model))); required: property<object> found: object
questions:
- ಠ_ಠ
- given java's type erasure limitations, techniques available me safely resolve these warnings?
- am safe suppress unchecked warning in original, non-typed method?
you need ramp generics skills.
instead of trying solve casts, try solving writing generic code yourself:
private <t> void createchangelistener(property<t> property) { property.addlistener(new changelistener<t>() { @override public void changed(observablevalue<? extends t> observable, t oldvalue, t newvalue) { foo.this.propertychanged(observable); } }); }
here, compiler can type checking. knows oldvalue , newvalue have type t, , can check not make incorrect assumptions.
now since addlistener(changelistener<? super t>)
accept listeners super types (<? super t>
!), following should fine, too:
private void createchangelistener(property<?> property) { property.addlistener(new changelistener<object>() { @override public void changed(observablevalue<?> observable, object oldvalue, object newvalue) { foo.this.propertychanged(observable); } }); }
the compiler should able verify code type safe.
make sure know differences between <?>
, <object>
, <t>
, <? super t>
, <? extends t>
, try learn how use them in own code. prefer broader version (extends
, super
can make difference! check java collections examples).
in above example, super
means allowed attach object
listener property<string>
, because supertype of string
.
Comments
Post a Comment