动态访问Java类的成员变量

时间:2019-11-21 15:36:53

标签: java

我有3个类,它们的变量名相同,但值不同。因此,我尝试根据用户提供的输入在公共对象中初始化类,然后打印相应的值。

public class A {
    public String s1 = "a1";
    public String s2 = "a2";
}

public class B {
    public String s1 = "b1";
    public String s2 = "b2";
}

public class C {
    public String s1 = "c1";
    public String s2 = "c2";
}

//This is not a working code, just a skeleton to express what I am trying to achieve
public class ClassDriver {
    public static void main(String[] args) throws Exception {
        String userInput = "A";
        //If it's A, then Class A specific values need to be printed at the end
        //If it's B, then Class B specific values need to be printed at the end
        //If it's C, then Class C specific values need to be printed at the end
        Class clazz;
        switch(userInput) {
        case "A":
            clazz = new A();
            break;
        case "B":
            clazz = new B();
            break;
        case "C":
            clazz = new C();
            break;
        default:
            throw new Exception("Not Implemented");
        }
        System.out.println(clazz.s1);
        System.out.println(clazz.s2);
    }
}

我不想使用以下反射选项,因为它要求用户将变量名作为参数传递(在下面的示例中为"s1"),并且它可能不是动态的。

Class aClass = A.class;
Field field = aClass.getField("s1");
System.out.println(field.get(new A()).toString());

我认为应该有其他更好的方法来处理这种情况,但是到目前为止我还无法弄清楚。所以有人可以给我一些建议吗?

2 个答案:

答案 0 :(得分:3)

您可以使用interface来定义每个类将实现的抽象功能层。

在创建实现该接口的类的实例时,可以确保该类支持该接口中定义的所需功能子集。

在您的情况下:

interface MyInterface { // Name this something sensible
    public String getS1();
    public String getS2();
}

public class A implements MyInterface {
    public String getS1() {
      return "a1";
    }
    public String getS2() {
      return "a2";
    }
}

public class B implements MyInterface {
    public String getS1() {
      return "b1";
    }
    public String getS2() {
      return "b2";
    }
}

稍后在您的代码中使用时:

...
MyInterface clazz; // Please rename this to something more appropriate
switch(userInput) {
    case "A":
        clazz = new A();
        break;
    case "B":
        clazz = new B();
        break;
    case "C":
        clazz = new C();
        break;
    default:
        throw new Exception("Not Implemented");
}
System.out.println(clazz.getS1());
System.out.println(clazz.getS2());

答案 1 :(得分:0)

正如几个人所评论的那样,使用接口通常是最好的方法,因为它对您的类没有其他限制。另一种选择(仅在某些情况下有效)是将此通用代码放入基类中,如果您永远不会单独实例化该基类,则该基类可能是抽象类。

这种方法仅在存在真正的is-A关系时才有效,并且在所有情况下那些公共字段实际上都是同一件事。例如如果A是Car,B是Truck,并且s1,s2是fuelType和fuelTankCapacity。卡车也可能有牵引重量,因此它们是不同的类别,但它们也有很多共同点。创建一个具有通用元素的类Vehicle,包括与之相关的代码和业务规则(例如,计算里程)。

请注意is-A关系存在的重要事实。汽车是“汽车”;卡车是“ A”型车辆。试图在不是“ is-A”的关系上继承继承几乎总是错误的。