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

Popular posts from this blog

html - Outlook 2010 Anchor (url/address/link) -

javascript - Why does running this loop 9 times take 100x longer than running it 8 times? -

Getting gateway time-out Rails app with Nginx + Puma running on Digital Ocean -