java反射 获取方法,Java反射:我如何获得java类的所有getter方法并调用它们

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!

解决方案

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 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 based on an object's bean properties.

public static Map 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 beanProperties(Object bean) {

try {

Map 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 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 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::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);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值