获取字段(成员变量)的相关getter/setter

rks48beu  于 2022-10-22  发布在  Java
关注(0)|答案(3)|浏览(150)

我有一个类MyClassFieldf,我想检索相关的getter/setter(如果存在)。我该怎么做?

  • 我检查了Field的方法,但没有一个返回Method
  • 我使用了Introspector.getBeanInfo(Class<?> beanClass)检索到的BeanInfo。它有一个方法getPropertyDescriptors(),它返回一个PropertyDescriptor数组,每个PropertyDescriptor都允许通过getReadMethod()getWriteMethod()来检索getter和setter。但似乎与Field没有任何连接。此外,似乎不可能获得特定PropertyDescriptor(例如,通过将字段名作为参数来检索);因此,即使有一种方法可以从PropertyDescriptor中获得Field,我也需要遍历所有PropertyDescriptors。这不是性能问题。
  • 注:*我不想依赖命名约定,所以请不要给出干扰字段名称的答案。字段myField的getter如果没有名称getMyFieldisMyField,那么它仍然是getter。
bvjxkvbb

bvjxkvbb1#

这是我的想法,但并不完全正确。检查方法名中是否包含字段名,以及返回类型和参数参数类型。我觉得如果没有关于字段的setter/getter方法的规则。这几乎是不可能的。

@Test
    void test_fieldGetterSetter() throws NoSuchFieldException {
    Field f = MyClass.class.getDeclaredField("name");
    Class<?> declaringClass = f.getDeclaringClass();

    Method[] declaredMethods = declaringClass.getDeclaredMethods();

    for (Method declaredMethod : declaredMethods) {
        String name = declaredMethod.getName();

        // Can also check return type, argument type to increase the correctness
        if (isFieldNameWithMethodName(f.getName(), name)) {
            String format = String.format("Field name is %s and possible method name is %s", f.getName(), name);
            System.out.println(format);
        }
    }
}

private boolean isFieldNameWithMethodName(String fieldName, String methodName) {
    if (methodName.toLowerCase().contains(fieldName.toLowerCase())) {
        return true;
    }

    return false;
}
carvr3hs

carvr3hs2#

事实证明,在Java中,getter/setter不仅仅是由它们的签名和行为(正如我所想的)定义的,还通过遵循命名约定来定义。
因此,为了为对象myObjectFieldmyField获取getter/setter,我们需要创建相应的getter/ssetter方法名methodName(使用Field.getName(),然后摆弄get/set和camelCase),然后调用myObject.getClass().getMethod(methodName, ...)。参数(...)可以通过Field.getType()来检索,并且必须根据我想要getter还是setter而有所不同。
证明命名很重要:对于这个类

public class ClassWithUnconventionalNaming {

    private int foo;
    public int myGetter() { return foo; }
    public void mySetter(int x) { this.foo = x; }
    public void setBaz(boolean x) { this.foo = 2; };

    private String bar;
    public String getBar() { return "hello world"; }
    public void setBar(String bar) { this.bar = bar; }

    private boolean baz;
    public boolean isBaz() { return baz; }
}

我运行了代码

ClassWithUnconventionalNaming myClass = new ClassWithUnconventionalNaming();
myClass.mySetter(5);

BeanInfo info = Introspector.getBeanInfo(ClassWithUnconventionalNaming.class);
for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
    String propertyName = pd.getName();
    System.out.println("property name: " + propertyName);
    Method getter = pd.getReadMethod();
    System.out.println("    getter: " + ((getter == null) ? "" : getter.getName()));
    Method setter = pd.getWriteMethod();
    System.out.println("    setter: " + ((setter == null) ? "" : setter.getName()));
}

并得到了输出

property name: bar
    getter: getBar
    setter: setBar
property name: baz
    getter: isBaz
    setter: setBaz
property name: class
    getter: getClass
    setter:
frebpwbc

frebpwbc3#

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ClassUtils {
/**
 * Returns the corresponding getter method for a field from this object
 *
 * @param field
 * @return
 * @throws NoSuchMethodException
 * @throws SecurityException
 */
public Method getGetterMethodForField(Field field) throws NoSuchMethodException, SecurityException {
    String fieldName = field.getName();
    String getterMethodName = "get" + fieldName.toUpperCase().charAt(0) + fieldName.substring(1);
    try
    {
        return this.getClass().getMethod(getterMethodName);
    }catch( NoSuchMethodException e ) {
        // If that fails try with "is" instead
        getterMethodName = "is" + fieldName.toUpperCase().charAt(0) + fieldName.substring(1);
        return this.getClass().getMethod(getterMethodName);
    }
}

/**
 * Returns the corresponding getter method for a field from the specified object
 *
 * @param field
 * @return
 * @throws NoSuchMethodException
 * @throws SecurityException
 */
public static Method getGetterMethodForField(Field field, Object obj) throws NoSuchMethodException, SecurityException {
    String fieldName = field.getName();
    String getterMethodName = "get" + fieldName.toUpperCase().charAt(0) + fieldName.substring(1);
    try
    {
        return obj.getClass().getMethod(getterMethodName);
    }catch( NoSuchMethodException e ) {
        // If that fails try with "is" instead
        getterMethodName = "is" + fieldName.toUpperCase().charAt(0) + fieldName.substring(1);
        return obj.getClass().getMethod(getterMethodName);
    }
}

/**
 * Returns the corresponding getter method for a field from the specified class
 *
 * @param field
 * @return
 * @throws NoSuchMethodException
 * @throws SecurityException
 */
public static Method getGetterMethodForField(Field field, Class clazz) throws NoSuchMethodException, SecurityException {
    String fieldName = field.getName();
    String getterMethodName = "get" + fieldName.toUpperCase().charAt(0) + fieldName.substring(1);
    try
    {
        return clazz.getMethod(getterMethodName);
    }catch( NoSuchMethodException e ) {
        // If that fails try with "is" instead
        getterMethodName = "is" + fieldName.toUpperCase().charAt(0) + fieldName.substring(1);
        return clazz.getMethod(getterMethodName);
    }
}

/**
 * Returns the corresponding getter method for a field from this object
 *
 * @param field
 * @return
 * @throws NoSuchMethodException
 * @throws SecurityException
 */
public Method getSetterMethodForField(Field field, Class<?> argType) throws SecurityException, NoSuchMethodException {
    String fieldName = field.getName();
    String setterMethodName = "set" + fieldName.toUpperCase().charAt(0) + fieldName.substring(1);

    do {
        try {
            Method method = this.getClass().getMethod(setterMethodName, argType);
            return method;
        } catch (NoSuchMethodException e) {

            // Check if the argument is a primitive
            if( org.apache.commons.lang3.ClassUtils.wrapperToPrimitive(argType) != null ) {
                argType = org.apache.commons.lang3.ClassUtils.wrapperToPrimitive(argType);
                try {
                    Method method = this.getClass().getMethod(setterMethodName, argType);
                    return method;
                } catch (NoSuchMethodException e2) {
                    argType = argType.getSuperclass();
                }
            }
            else {
                // Check for interfaces
                for( Class<?> baseArgType : org.apache.commons.lang3.ClassUtils.getAllInterfaces(argType) ) {
                    try {
                        Method method = this.getClass().getMethod(setterMethodName, baseArgType);
                        return method;
                    } catch (NoSuchMethodException e2) {
                    }
                }
                argType = null;
            }

        }
    } while (argType != null);

    throw new NoSuchMethodException(setterMethodName);
}

}

相关问题