使用“ Reflect”从扩展的抽象类获取参数值

时间:2018-10-10 06:19:15

标签: java class reflection casting

我想从扩展类中获取param2的值,该扩展类具有与抽象类'B'共享的公共属性,如下所示:

import java.lang.reflect.Field;

public class Fields {

    public class A{

        public abstract class B{
            int param1;
            String param2;
            public abstract void B ();
        }

        public class B0 extends B{
            @Override
            public void B() {
                this.param1 = 0;
                this.param2 = "Mario";
            }                                    
        }

        public class B1 extends B{
            @Override
            public void B() {
                this.param1 = 1;
                this.param2 = "Anna";
            }            
        }        

        B1 b1 = new B1();        

        public A (){
            b1.B();
        }

        public B0 GetB(Object AnyB){
            B0 tmp_b0 = (B0) AnyB;
            return tmp_b0;
        }
    }

    public Fields(){
        A a = new A();
        Field[] f = a.getClass().getDeclaredFields();

        for (int i = 0; i<f.length; i++){
            f[i].setAccessible(true);
            Object obj = f[i];
            String p2;
            p2 = a.GetB(obj).param2;
            System.out.println(p2);
        }        
    }

    public static void main(String [] args){
        Fields f = new Fields();        
    }
}

通常,指令B0 tmp_b0 = (B0) AnyB;是正确的,但是在运行时出现错误:Exception in thread "main" java.lang.ClassCastException: java.lang.reflect.Field cannot be cast to Fields$A$B0

为什么?

有一种方法可以获取参数param1param2的值。

有办法吗?

谢谢

1 个答案:

答案 0 :(得分:3)

(注意:这个答案是在问题完全改变之前写的。我现在就这样保留它,以希望问题能够回滚。)

  

指令B0 tmp_b0 = (B0) AnyB;正确无误,

这是有效的Java代码,但我不希望它在这种情况下能工作。您当前正在传递Field引用-这不是{em> B0,所以您遇到了异常。

您不想传递Field本身-我怀疑您想针对a传递字段的 value

Object fieldValue = f[i].get(a);
String p2 = a.GetB(fieldValue);

即使那样,您仍然会为ClassCastException字段获得一个b1,因为它的执行时类型为B1,但是您正在尝试转换为B0B1的实例是不是 B0的实例。

尚不清楚您要在此处实现什么目标-当您从未创建实例时,为什么要拥有B0类,但我建议尝试使事情正常工作首先没有反射,然后当您使用反射时,请区分字段的概念(由Field表示)和字段的值。

(我还建议不要过多地使用嵌套类,并遵循Java命名约定,但是它们有些分开。)