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