reflection - Get the list of property of Object from List of Object dynamically in java -


i trying list of property ,means have class user , has property name , have public method getname() name of user, problem want create method takes generic list , , method name , , helping of stream api list of property of class.

means if pass list of user , method name 'getname' in test method returns list of username.

public static boolean test(list<?> propertylist) throws exception{                 class<?> c = class.forname(propertylist.get(0).getclass().getcanonicalname());                 method method = c.getdeclaredmethod(methodname);               !propertylist.stream().map(c::method).allmatch(new hashset<>()::add);         } 

you can’t put class object , method object using :: c::method. can express dynamic invocation using method::invoke, unfortunately, that’ll incompatible expected type function, because method.invoke can throw checked exceptions.

so can use lambda expression encapsulating dynamic invocation , catching reflective exceptions:

public static boolean test(list<?> propertylist, string methodname) throws exception{     method method = propertylist.get(0).getclass().getdeclaredmethod(methodname);      return !propertylist.stream().map(x -> {         try {             return method.invoke(x);         } catch (reflectiveoperationexception ex) {             throw new runtimeexception("invoking "+method, ex);         }     }).allmatch(new hashset<>()::add); } 

if using method function recurring problem in code, can create factory method utilizing java’s built-in features dynamic class creation:

public static boolean test(list<?> propertylist, string methodname) throws exception {     method method = propertylist.get(0).getclass().getdeclaredmethod(methodname);     return !propertylist.stream().map(tofunction(method)).allmatch(new hashset<>()::add); } public static function tofunction(method m) throws illegalaccessexception {     return methodhandleproxies.asinterfaceinstance(function.class,         methodhandles.lookup().unreflect(m)); } 

but note there conceptional flaws in method. relies on list not being empty , imposes unintended constraints on type of first list element. list may contain elements of different actual types having common base type declared element type. if elements have same type, getdeclaredmethod search specific class , ignore inherited methods.

in other words, using "tostring" method name can fail procedure not object.tostring, may fail find method or may find method in first element’s type specific other elements of list.

a better design let caller provide type:

public static <t> boolean test(     list<? extends t> propertylist, class<t> type, string methodname) throws exception {      method method = type.getmethod(methodname);     return !propertylist.stream().map(tofunction(method)).allmatch(new hashset<>()::add); } 

this allows pass in list having declared element type being more specific type of class search method , having particular elements of more specific type declare element type , supports empty lists.

note getmethod’s search consider inherited methods public methods.


Comments