0

我想检索 Java 类中给定属性的所有访问器。我已经尝试了一些东西,但它没有给出我期望的输出。例如:

public class demo {
    private String abc;

    public String getAbc() {
        return abc;
    }

    public void setAbc(String abc) {
        this.abc = abc;
    }

    public String fetchAbc() {
        return abc;
    }
}

在这里,该abc属性有两个 getter,我想在我的项目中找到出现的情况。我尝试了以下代码,它使用了 BeanInfo API,但它只给了我一个访问器:

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;

public class BeanDemo {

    public void myMethod() throws IntrospectionException {
        BeanInfo beanInfo = Introspector.getBeanInfo(demo.class);

        for (PropertyDescriptor property : beanInfo.getPropertyDescriptors()) {
            //all attributes of class.
            property.getReadMethod(); // getter
            property.getWriteMethod(); // setter
        }
    }
}

谁能告诉是否有另一个 API 可以用来完成这个?我可以玩反射,但这不是正确的方法。谢谢。

4

3 回答 3

1

首先: 遵循 JavaBean 约定是有帮助的。 如果您有一个说“检索”的方法,但它是一个实际的 getter,那么它比 Java 更让您感到困惑 - 为什么应该有不止一种方法来获取一个字段?

第二: 反思是你的朋友。 您可以以非常轻松的方式反射性地提取有关对象的信息,并检索您想要的结果。您应该查看Reflection Trail,因为它包含大量有用的信息来帮助您入门。

这是一个小示例 - 它将获取此类中标记为“get”的所有方法。

public class StackOverflow {
    public static void main(String[] args) throws ClassNotFoundException {
        Method[] methods = Class.forName("Fake").getMethods();
        for(Method m : methods) {
            if(!m.getDeclaringClass().equals(Object.class) && m.toGenericString().contains("get")) {
                System.out.println(m.toGenericString());
            }
        }
    }
}

class Fake {
    private String objField;
    private int primitiveField;
    private boolean[] arrayField;

    public void setObjField(final String theObjField) {
        objField = theObjField;
    }

    public void setPrimitiveField(final int thePrimitiveField) {
        primitiveField = thePrimitiveField;
    }

    public void setArrayField(final boolean[] theArrayField) {
        arrayField = theArrayField;
    }

    public String getObjField() {
        return objField;
    }

    public int getPrimitiveField() {
        return primitiveField;
    }

    public boolean[] getArrayField() {
        return arrayField;
    }
}

上述输出:

public java.lang.String Fake.getObjField()
public int Fake.getPrimitiveField()
public boolean[] Fake.getArrayField()
于 2013-04-03T04:36:22.203 回答
0

Reflection is going only to look at the names and signatures of the methods, it does not look at what they actually do. So can you reliably identify an get/set on that basis?

You can identify all fields: aaa, bbb etc, and then look for all methods whose signatures look like accessors and whose names contain aaa or bbb etc. So you'd find getAaa(), setBbb() and fetchAaa(), and perhaps even bbbFetcher(), but you cannot be sure that any of these really are what you are looking for. Even were you to scan the source it's tricky: Consider

getMagnitude() { return squareRoot( x squared plus y squared) } 

is that a getter?

Bottom line: pattern matching on names of fields and methods will give you candidates, but you have to devise the matching rules that fit your needs.

于 2013-04-03T04:50:44.460 回答
0

我会鼓励你“玩反射”,因为这正是正确的方法。

从这里开始,进行一般的反思,或者从这里开始,进行课程。您可能还会发现此参考页面很有用。

这里有一个提示:

Method[] methods = demo.class.getMethods();
for (int i=0; i<methods.length; i++) {
    Method method = methods[i];
    // Take a look at the Method documentation to find out more:
    // http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Method.html

    // Or, look at the Method tutorial here:
    // http://docs.oracle.com/javase/tutorial/reflect/member/method.html
}

至少检查一下Class<T>班级Method班级。

于 2013-04-03T04:27:48.857 回答