我写了一个有很多getter的java类..现在我想获取所有getter方法并在某个时候调用它们。我知道有一些方法,比如getMethods()或getMethod(String name,Class ... parameterTypes) ,但我只是想得到吸气剂......,使用正则表达式?谁能告诉我?谢谢!
答案 0 :(得分:143)
请勿使用正则表达式,请使用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());
}
通常您不需要Object.class中的属性,因此您将使用带有两个参数的方法:
Introspector.getBeanInfo(yourClass, stopClass)
// usually with Object.class as 2nd param
// the first class is inclusive, the second exclusive
BTW:有一些框架可以帮助您,并为您提供高级视图。例如。
commons / beanutils有方法
Map<String, String> properties = BeanUtils.describe(yourObject);
(docs here)就是这样做:找到并执行所有的getter并将结果存储在map中。不幸的是,BeanUtils.describe()
在返回之前将所有属性值转换为字符串。 WTF。谢谢@danw
<强>更新强>
这是一个基于对象的bean属性返回Map<String, Object>
的Java 8方法。
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();
}
}
但是,您可能希望使错误处理更加健壮。对于样板,很抱歉,检查异常会阻止我们在这里完全正常运行。
原来Collectors.toMap()讨厌空值。以下是上述代码的更为命令式版本:
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();
}
}
使用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();
}
}
这是一个番石榴版本:
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);
}
}
答案 1 :(得分:18)
您可以使用Reflections框架
import org.reflections.ReflectionUtils.*;
Set<Method> getters = ReflectionUtils.getAllMethods(someClass,
ReflectionUtils.withModifier(Modifier.PUBLIC), ReflectionUtils.withPrefix("get"));
答案 2 :(得分:9)
// 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());
}
答案 3 :(得分:8)
Spring为Bean内省提供了一个简单的BeanUtil method:
PropertyDescriptor pd = BeanUtils.getPropertyDescriptor(clazz, property);
Method getter = pd.getReadMethod();
答案 4 :(得分:1)
此代码已经过测试。
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();
}
}
答案 5 :(得分:0)
为什么不使用简单的Java? ...
/
...
答案 6 :(得分:-4)
您应该在每个bean中维护一个通用的getter,以便调用getAttribute1(),您应该能够调用一个通用的getter get(“Attribute1”)
这个通用的getter会调用正确的getter
Object get(String attribute)
{
if("Attribute1".equals(attribute)
{
return getAttribute1();
}
}
这种方法涉及到在每个bean中维护这个单独的列表,但这样可以避免出现性能问题的反射,因此如果编写需要具有良好性能的生产代码,则可以对所有bean使用上述模式。 / p>
如果某些测试代码或实用程序代码没有高性能要求,那么最好采用其他方法,因为这种方法容易出错,除非您可以编写某种编译时检查器来确保这种通用的getter函数有效所有属性。