Java Reflection: How can I get the all getter methods of a java class and invoke them
Don't use regex, use the Introspector
:
for(PropertyDescriptor propertyDescriptor :
Introspector.getBeanInfo(yourClass).getPropertyDescriptors()){
// propertyEditor.getReadMethod() exposes the getter
// btw, this may be null if you have a write-only property
System.out.println(propertyDescriptor.getReadMethod());
}
Usually you don't want properties from Object.class, so you'd use the method with two parameters:
Introspector.getBeanInfo(yourClass, stopClass)
// usually with Object.class as 2nd param
// the first class is inclusive, the second exclusive
BTW: there are frameworks that do that for you and present you a high-level view. E.g.
commons/beanutils has the method
Map<String, String> properties = BeanUtils.describe(yourObject);
(docs here) which does just that: find and execute all the getters and store the result in a map. Unfortunately, BeanUtils.describe()
converts all the property values to Strings before returning. WTF. Thanks @danw
Update:
Here's a Java 8 method that returns a Map<String, Object>
based on an object's bean properties.
public static Map<String, Object> beanProperties(Object bean) {
try {
return Arrays.asList(
Introspector.getBeanInfo(bean.getClass(), Object.class)
.getPropertyDescriptors()
)
.stream()
// filter out properties with setters only
.filter(pd -> Objects.nonNull(pd.getReadMethod()))
.collect(Collectors.toMap(
// bean property name
PropertyDescriptor::getName,
pd -> { // invoke method to get value
try {
return pd.getReadMethod().invoke(bean);
} catch (Exception e) {
// replace this with better error handling
return null;
}
}));
} catch (IntrospectionException e) {
// and this, too
return Collections.emptyMap();
}
}
You probably want to make error handling more robust, though. Sorry for the boilerplate, checked exceptions prevent us from going fully functional here.
Turns out that Collectors.toMap() hates null values. Here's a more imperative version of the above code:
public static Map<String, Object> beanProperties(Object bean) {
try {
Map<String, Object> map = new HashMap<>();
Arrays.asList(Introspector.getBeanInfo(bean.getClass(), Object.class)
.getPropertyDescriptors())
.stream()
// filter out properties with setters only
.filter(pd -> Objects.nonNull(pd.getReadMethod()))
.forEach(pd -> { // invoke method to get value
try {
Object value = pd.getReadMethod().invoke(bean);
if (value != null) {
map.put(pd.getName(), value);
}
} catch (Exception e) {
// add proper error handling here
}
});
return map;
} catch (IntrospectionException e) {
// and here, too
return Collections.emptyMap();
}
}
Here's the same functionality in a more concise way, using JavaSlang:
public static Map<String, Object> javaSlangBeanProperties(Object bean) {
try {
return Stream.of(Introspector.getBeanInfo(bean.getClass(), Object.class)
.getPropertyDescriptors())
.filter(pd -> pd.getReadMethod() != null)
.toJavaMap(pd -> {
try {
return new Tuple2<>(
pd.getName(),
pd.getReadMethod().invoke(bean));
} catch (Exception e) {
throw new IllegalStateException();
}
});
} catch (IntrospectionException e) {
throw new IllegalStateException();
}
}
And here's a Guava version:
public static Map<String, Object> guavaBeanProperties(Object bean) {
Object NULL = new Object();
try {
return Maps.transformValues(
Arrays.stream(
Introspector.getBeanInfo(bean.getClass(), Object.class)
.getPropertyDescriptors())
.filter(pd -> Objects.nonNull(pd.getReadMethod()))
.collect(ImmutableMap::<String, Object>builder,
(builder, pd) -> {
try {
Object result = pd.getReadMethod()
.invoke(bean);
builder.put(pd.getName(),
firstNonNull(result, NULL));
} catch (Exception e) {
throw propagate(e);
}
},
(left, right) -> left.putAll(right.build()))
.build(), v -> v == NULL ? null : v);
} catch (IntrospectionException e) {
throw propagate(e);
}
}
How to call all getter methods of a class in a loop?
You could access declared methods of a class that way:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Other {
public static void main(String [] args) {
Person p = new Person("Max", 12);
Class<?> c = p.getClass();
Method[] allMethods = c.getDeclaredMethods();
System.out.print( "Person's attributes: ");
for (Method m : allMethods) {
m.setAccessible(true);
String result;
try {
result = m.invoke(p).toString();
System.out.print(result + " ");
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}```
Reflector: How to list getters of a class and invoke them in Java?
PropertyDescriptor.getReadMethod()
returns a Method
object.
Simply use Method.invoke(Object instance, Object... args)
.
Something in the lines of...
for(PropertyDescriptor propertyDescriptor :
Introspector.getBeanInfo(User.class,Object.class).getPropertyDescriptors()){
try {
Object value = propertyDescriptor
.getReadMethod()
.invoke(myUserInstance, (Object[])null);
}
catch (IllegalAccessException iae) {
// TODO
}
catch (IllegalArgumentException iaee) {
// TODO
}
catch (InvocationTargetException ite) {
// TODO
}
}
Java Reflection : Accessing getter method
DEfine the class, then in the instance get all the methods then use a stream to filter the getters only
public class Pint {
private int x;
private int y;
private int z;
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getZ() {
return z;
}
and then
Arrays.stream(p.getClass().getDeclaredMethods()).filter(x -> x.getName().contains("get")).forEach(System.out::println);
Best way of invoking getter by reflection
I think this should point you towards the right direction:
import java.beans.*
for (PropertyDescriptor pd : Introspector.getBeanInfo(Foo.class).getPropertyDescriptors()) {
if (pd.getReadMethod() != null && !"class".equals(pd.getName()))
System.out.println(pd.getReadMethod().invoke(foo));
}
Note that you could create BeanInfo or PropertyDescriptor instances yourself, i.e. without using Introspector. However, Introspector does some caching internally which is normally a Good Thing (tm). If you're happy without a cache, you can even go for
// TODO check for non-existing readMethod
Object value = new PropertyDescriptor("name", Person.class).getReadMethod().invoke(person);
However, there are a lot of libraries that extend and simplify the java.beans API. Commons BeanUtils is a well known example. There, you'd simply do:
Object value = PropertyUtils.getProperty(person, "name");
BeanUtils comes with other handy stuff. i.e. on-the-fly value conversion (object to string, string to object) to simplify setting properties from user input.
Java reflection - how to call getter/setter method?
currentObject.getClass().getMethod(methodName);
Since methods can be overloaded, just the name of the method is not enough to look up the method. You need to provide the types of the arguments as well (and a setter is typically not a no-arg method).
Try something like
currentObject.getClass().getMethod(methodName, objectInputArr[i].getClass());
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Related Topics
Org.Glassfish.Jersey.Servlet.Servletcontainer Classnotfoundexception
How to Demonstrate Java Multithreading Visibility Problems
Why Is Javac Failing on @Override Annotation
Java Web Start Support in Java 9 and Beyond
How to Correctly Use Custom Renderers to Paint Specific Cells in a Jtable
Including Images with an Executable Jar
Spring Autowiring Class VS. Interface
How to Properly Configure Implicit/Explicit Waits and Pageloadtimeout Through Selenium
Java Jdbc MySQL Exception: "Operation Not Allowed After Resultset Closed"
Discord Jda - Invalid Member List
Jpanel Positions and Sizes Changes According to Screensize
How to Tune Tomcat 5.5 Jvm Memory Settings Without Using the Configuration Program
Using Setvalueat to Recreate Mutually Exclusive Check Boxes
Appearance of Java Security Dialog
Simpledateformat Parse(String Str) Doesn't Throw an Exception When Str = 2011/12/12Aaaaaaaaa