代码之家  ›  专栏  ›  技术社区  ›  Kjara

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

  •  -1
  • Kjara  · 技术社区  · 8 年前

    Field f 某个阶层的 MyClass 我想检索关联的getter/setter,如果它存在的话。我该怎么做?

    • 我查了一下 字段 ,但甚至没有一个返回 Method .
    • 我和他一起玩 BeanInfo Introspector.getBeanInfo(Class<?> beanClass) . 它有一个方法 getPropertyDescriptors() 返回一个 PropertyDescriptor 允许通过检索getter和setter getReadMethod() getWriteMethod() . 但似乎与 字段 属性描述器 (例如,通过提供一个字段名作为参数来检索);所以即使有办法获得 字段 属性描述器 ,我需要遍历所有 PropertyDescriptors . 这不是表演。

    注: 我不想依赖命名约定,所以请不要给出一个摆弄域名的答案。一个领域的开拓者 myField getMyField isMyField

    2 回复  |  直到 8 年前
        1
  •  0
  •   sendon1982    8 年前

    这是我的想法,但并不完全正确。

        @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;
    }
    
        2
  •  -1
  •   Kjara    8 年前

    事实证明,在Java中,getter/setter不仅仅是由它们的签名和行为(如我所想)定义的,而且还通过遵循命名约定来定义的。

    所以为了得到一个 Field myField 对象的 myObject ,我们需要创建相应的getter/setter方法名 methodName Field.getName() 然后摆弄 get / set 然后打电话 myObject.getClass().getMethod(methodName, ...) . 参数( ... )可以通过使用 Field.getType() 根据我想要的是盖特还是塞特,一定会有所不同。

    证明命名很重要: 为了这个班

    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: