【问题标题】:Problems with Reflection JAVA反射JAVA的问题
【发布时间】:2017-06-02 21:20:44
【问题描述】:

早上好。我通过反射从类的字段中获取值。我通过参数获取对象,但是当我显示我得到的值时,它是空白的。我得到了属性,但没有得到值。从我注意到的情况来看,它似乎没有捕获传递的对象的实例。感谢您的帮助。

public static void transformarCamposCaixaAlta(BaseModel bm) {
    Class<?> classe = bm.getClass();
    for(Field item : classe.getDeclaredFields()) {
        item.setAccessible(true);

        if (item.getType() == BaseModel.class) {
            try {
                transformarCamposCaixaAlta((BaseModel) item.get(bm));
            } catch (IllegalArgumentException | IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        if (item.isAnnotationPresent(FieldUpperCase.class)) {
            try {
                if(item.get(bm) != null) {

                    System.out.println("Valor: "+ item.get(bm).toString() + " Tipo: "+ item.getName());
                    System.out.println("------");
                    item.set(bm, ((String)item.get(bm)).toUpperCase());
                }
            } catch (IllegalArgumentException | IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }
}

【问题讨论】:

  • "...它是空白的"你能详细说明一下,数据类型是什么?
  • 你试过minimal reproducible example吗?这对我来说看起来不错,所以检查一下使用的实例可能
  • 是的,我用最少的示例和功能进行了测试。
  • 请向minimal reproducible example 明确说明实际行为和预期行为。
  • 顺便说一句,如果你想检查每个类型item.getType() == BaseModel.class 将无法管理子类。循环通过Class.getGenericSuperclass 可以提供帮助,

标签: java reflection


【解决方案1】:

我建议尝试简化您的示例并在每个步骤中打印或记录以查看哪里出错了。如果没有您的课程或注释,很难准确地说出,但您发布的所有内容看起来都是正确的。 您是否可以发布您的 BaseModel 类和注释,或者如果它们是复杂类,则可以发布如下简化示例。

也许这个基本的例子会帮助你走上正轨:

public static void basicReflection(Object obj) throws IllegalAccessException {
    Class<?> objClass = obj.getClass();
    System.out.println("obj: " + obj.getClass());

    Field[] fields = objClass.getDeclaredFields();
    for(Field field : fields) {
        field.setAccessible(true);
        System.out.println("Field: " + field.getName() + " value: " + field.get(obj));
        if (field.getType() == Bar.class) {
            System.out.println("Field is a Bar");
        }
    }
}

一些基本的 POJO:

public class Foo {
    public Foo(){}
    private Integer someInt = 123;
    private Long someLong = 987654321L;
    private String someString = "qwertyuiop";
    private Bar bar = new Bar();
}

调用类做反射的例子:

public class Main {
    public static void main(String[] args) throws Exception {
        Foo foo = new Foo();
        basicReflection(foo);
    }
}

结果控制台输出:

obj: class com.kaitait.reflection.Foo
Field: someInt value: 123
Field: someLong value: 987654321
Field: someString value: qwertyuiop
Field: bar value: com.kaitait.reflection.Bar@61bbe9ba
Field is a Bar

您可能还会发现this post 很有帮助。

【讨论】:

  • 我的类BaseModel是超类,所有对象模型都扩展了BaseModel,它只有模型共有的属性如:dateRegistration。我在保存到 GenericDao 之前调用方法:transformarCamposCaixaAlta,以转换带有大写注释的字段。
  • 你试过不加注解吗?我认为这可能是您的问题所在。
  • 非常感谢@Kai的帮助,我使用instanceof检查每个对象,我不知道为什么我可以获取对象的实例并且有一个变量类放在其中之一对于每次交互,它都会获得超类,直到它为 null 。再次感谢您的帮助。我无法将代码放在这个答案中,但我把它作为帖子的回应,我认为它一直在那里。 :)
【解决方案2】:

非常感谢@Kai 的帮助,我使用 instanceof 来检查每个对象,我不知道为什么我可以获取对象的实例并且有一个变量类,我在其中一个 while 中为每次交互它获取超类,直到它为 null 。再次感谢您的帮助。

类类 = bm.getClass();

    do {
        for(Field item : classes.getDeclaredFields()) {
            item.setAccessible(true);
            try {
                if (item.get(bm) != null) {
                    if (item.get(bm) instanceof BaseModel) {
                        try {
                            if (!item.isAnnotationPresent(Transient.class))
                            transformarCamposCaixaAlta(item.get(bm));
                        } catch (IllegalArgumentException | IllegalAccessException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            } catch (IllegalArgumentException | IllegalAccessException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }

            if (item.isAnnotationPresent(FieldUpperCase.class)) {
                try {
                    if(item.get(bm) != null) {
                        item.set(bm, ((String)item.get(bm)).toUpperCase());
                    }
                } catch (IllegalArgumentException | IllegalAccessException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

        }
    } while((classes = classes.getSuperclass()) != null);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多