I write a java class which has many getters..now I want to get all getter methods and invoke them sometime..I know there are methods such as getMethods() or getMethod(String name, Class... parameterTypes) ,but i just want to get the getter indeed..., use regex? anyone can tell me ?Thanks!
7 Answers
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);
}
}

- 53,120
- 14
- 139
- 204

- 292,901
- 67
- 465
- 588
-
6Wow. I didn't know you could do that! Cool! – Cody S Dec 15 '11 at 17:19
-
Thanks ..i test the code ... the end of the output is **public final native java.lang.Class java.lang.Object.getClass()**...i don't want to invoke it..how to remove it ? – user996505 Dec 15 '11 at 17:30
-
1@user996505 Use Introspector.getBeanInfo(yourClass, Object.class) , to search all classes below Object – Sean Patrick Floyd Dec 15 '11 at 17:33
-
Just an FYI, `BeanUtils.describe(yourObject);` returns `Map
` not Map – danw May 22 '15 at 03:13`. -
@danw you're right. what a nightmarish mess. will update my answer – Sean Patrick Floyd May 22 '15 at 07:09
-
One thing to keep be aware of here is that this approach will not work in Android environments due to the fact that the java.beans.Introspector class, and set of related classes, don't exist in the Android SDK. With that said, you'd better served an approach similar to the one that dku.rajkumar mentioned below – Ryan J. McDonough Nov 08 '15 at 16:25
-
2@RyanJ.McDonough this was a plain Java question, not an Android one. The Introspector is THE standard mechanism for standard Java. Android may or may not have a different mechanism, but that doesn't invalidate my answer – Sean Patrick Floyd Nov 08 '15 at 17:41
-
Totally agree and I wasn't attempting to invalidate your answer and did not down vote you. I was simply noting a fact that you should be aware of in case you end up trying to reuse code in "Java-like" environments such as Android. I find it REALLY annoying that Android doesn't have this functionality. – Ryan J. McDonough Nov 09 '15 at 13:28
-
@RyanJ.McDonough well to be fair, the Getter / Setter concept is not used that much anymore anyway. It was important in the days when Java was mapped to and from JSP, XML etc, but these days, Mapping technologies are often more explict and perhaps JavaBeans will eventually just go away, as it is very verbose and error-prone – Sean Patrick Floyd Nov 09 '15 at 13:53
-
True, but it is very annoying to have incompatible Java environments floating around. The java.beans.* package is just one case and there's probably more. – Ryan J. McDonough Nov 10 '15 at 14:54
-
Use apache commons BeanMap to decorate a bean as a Map
, it uses reflection to implement get() and put() methods instead of loading all properties regardless of need. – user515655 Jan 09 '16 at 19:00 -
@hiaclibe need more info to help. here's a working example, without NPEs: http://ideone.com/AXoH41 – Sean Patrick Floyd Dec 14 '16 at 14:59
-
Perhaps my object itself contains some null values for instance vars (e.g. interfaces...). I try to convert my object to map
for using it as custom HTTP header (with prefix before each key!). After receiving it at the other side, I need to convert back to object again. – hiaclibe Dec 15 '16 at 09:58 -
@hiaclibe if you need String,String, you can pipe the values to String.valueOf(), thus also preventing NPEs – Sean Patrick Floyd Dec 15 '16 at 10:23
-
Java 8 solution does not support nulls in values. It throws NullPointerException. It is a known issue, see here: http://stackoverflow.com/questions/24630963/java-8-nullpointerexception-in-collectors-tomap – Paweł Skorupiński Mar 07 '17 at 14:16
-
@PawełSkorupiński yup, and there's not really a sane workaround in the Streams API. Added a more imperative example. – Sean Patrick Floyd Mar 07 '17 at 14:38
-
I think all of these examples also return methods that happen to be called getXXX, but which aren't backed by any field. – Hervian May 05 '20 at 18:15
-
@Hervian yes, and that is correct according to the JavaBeans specification. Having a corresponding field is a convention, but not a requirement. JavaBeans properties are defined through getters and/or setters, not fields. – Sean Patrick Floyd May 05 '20 at 19:51
-
Yes, good point. In my case I use private fields with getter and setters generated by Lombok - and often some utility methods added to the class. Sometimes I must admit that they are called getXXX, like getPrettyPrintedFieldA, but for my use case I only want the getters that are backed by fields. But I guess I must match up against field names (or change the getXXX method). – Hervian May 05 '20 at 20:28
-
@Hervian in that case, just add another .filter() step to any of the solutions above, and check whether a field named `propertyDescriptor.getName()` is defined. Of course that doesn't verify that the getter actually reads this field, but it's a start. – Sean Patrick Floyd May 05 '20 at 21:09
You can use Reflections framework for this
import org.reflections.ReflectionUtils.*;
Set<Method> getters = ReflectionUtils.getAllMethods(someClass,
ReflectionUtils.withModifier(Modifier.PUBLIC), ReflectionUtils.withPrefix("get"));

- 750
- 1
- 9
- 27

- 476
- 4
- 8
-
7Not all getters start with "get": (1) boolean-returning getters may start with "is"; (2) a BeanInfo class may state that additional methods are getters. You should really add a restriction like _if you know that all your getters start with "get", you can do this_. – toolforger Dec 15 '17 at 10:26
Spring offers an easy BeanUtil method for Bean introspection:
PropertyDescriptor pd = BeanUtils.getPropertyDescriptor(clazz, property);
Method getter = pd.getReadMethod();

- 9,812
- 7
- 72
- 81
-
And `BeanUtils.getPropertyDescriptors(clazz)` to get all properties. – Dario Seidl Jun 21 '22 at 11:45
// Get the Class object associated with this class.
MyClass myClass= new MyClass ();
Class objClass= myClass.getClass();
// Get the public methods associated with this class.
Method[] methods = objClass.getMethods();
for (Method method:methods)
{
System.out.println("Public method found: " + method.toString());
}

- 18,414
- 7
- 41
- 58
-
4Yes, but you'll also have to check for each method that it's public, non-static, returns void, expects no parameter and follows the get/isXyz name convention. The Introspector does all of that for you, plus it caches the BeanInfo data internally for other applications. – Sean Patrick Floyd Dec 15 '11 at 17:34
-
Sure, but what if you don't want to add the library, you need it on Android, for example, copy it here. http://www.docjar.com/html/api/java/beans/Introspector.java.html#511 – Luiz Felipe May 19 '21 at 18:18
Why not use simple Java? ...
public static Map<String, Object> beanProperties(final Object bean) {
final Map<String, Object> result = new HashMap<String, Object>();
try {
final PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(bean.getClass(), Object.class).getPropertyDescriptors();
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
final Method readMethod = propertyDescriptor.getReadMethod();
if (readMethod != null) {
result.put(propertyDescriptor.getName(), readMethod.invoke(bean, (Object[]) null));
}
}
} catch (Exception ex) {
// ignore
}
return result;
}
...

- 31
- 2
This code is tested OK.
private void callAllGetterMethodsInTestModel(TestModel testModelObject) {
try {
Class testModelClass = Class.forName("com.example.testreflectionapi.TestModel");
Method[] methods = testModelClass.getDeclaredMethods();
ArrayList<String> getterResults = new ArrayList<>();
for (Method method :
methods) {
if (method.getName().startsWith("get")){
getterResults.add((String) method.invoke(testModelObject));
}
}
Log.d("sayanReflextion", "==>: "+getterResults.toString());
} catch (ClassNotFoundException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}

- 352
- 2
- 21
-
I'm sorry this is a terrible approach. Just because a method starts with `get` does not mean it's a getter. – Madbreaks Aug 28 '20 at 16:41
-
That's exactly what it means `if (name.startsWith(GET_PREFIX))` http://www.docjar.com/html/api/java/beans/Introspector.java.html#511 – Luiz Felipe May 19 '21 at 18:10
public static void retrieveAndExecuteBeanGetterMethods(Object bean) throws IntrospectionException {
List<PropertyDescriptor> beanGettersList = Arrays.asList(
Introspector.getBeanInfo(bean.getClass(), Object.class)
.getPropertyDescriptors());
beanGettersList.stream()
.filter(pd -> Objects.nonNull(pd.getReadMethod()))
.collect(Collectors.toMap(PropertyDescriptor::getName,
pd -> {
try {
return pd.getReadMethod().invoke(bean);
} catch (Exception e) {
return null;
}
}));
}

- 1
-
Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 18 '22 at 23:26