使用反射时访问超类的隐藏字段

时间:2015-07-07 11:45:27

标签: java reflection hiddenfield

我将通过一个例子来解释它,因为我无法解释这个问题。

让我们选择以下两节课,

em

现在,我想要获得汽车和奥迪系列。所以我可以用,

public class Vehicle {
    public String series = "Sedan";
}

public class Audi extends Vehicle {
    public String series = "A8";
}

我的问题出现了: 但是如果我在编译期间无法访问Audi audi = new Audi(); Vehicle vehicle = audi; String audiSeries = audi.series; //This will give me "A8" String vehicleSeries = vehicle.series; //This will give me "Sedan" Vehicle类,并且只能使用反射来获取对象,那么我该如何获得Audi

vehicle's series
  

输出: A8

     

是否有Class audiClass = Class.forName("Audi"); Class vehicleClass = Class.forName("Vehicle"); Object audiObj = audiClass.newInstance(); Field audiSeries = audiClass.getField("series"); System.out.println(audiSeries.get(audiObj)); 课程'Vehicle字段“Sedan”   以上方法。

P.S:我无法改变设计以避免此问题。

3 个答案:

答案 0 :(得分:1)

我自己很惊讶,你可以通过将ist强制转换为车辆来访问Vehicle's Field。

你的Approch有效,你只需要使用车辆类中的字段进行最后一步:

Audi audi = new Audi();
Vehicle vehicle = audi;
String audiSeries = audi.series; 
System.out.println("direct-audi: " + audiSeries);
String vehicleSeries = vehicle.series; 
System.out.println("direct-vehicle: " + vehicleSeries);


Class audiClass = Class.forName(Audi.class.getName());
Class vehicleClass = Class.forName(Vehicle.class.getName());


Object audiObj = audiClass.newInstance();
Field audiSeriesField = audiClass.getField("series");
Field vehicleSeriesField = vehicleClass.getField("series");

System.out.println("reflection-audi: " + audiSeriesField.get(audiObj));
System.out.println("reflection-vehicle: " +  vehicleSeriesField.get(audiObj));

结果:

direct-audi: A8
direct-vehicle: Sedan
reflection-audi: A8
reflection-vehicle: Sedan

如果您不了解超类名称,可以使用Class vehicleClass = audiClass.getSuperclass();

答案 1 :(得分:0)

如果您可以在超类中添加getter,这将为您解决问题:

public class Audi extends Vehicle {
    String myString = "A8";

    public static void main(String[] args) throws Throwable {
        System.out.println(new Audi().myString);        // outputs A8
        System.out.println(new Audi().getMyString());   // outputs Sedan
    }

}

class Vehicle {
    String myString = "Sedan";

    public String getMyString() {
        return myString;
    }
}

答案 2 :(得分:0)

可以以这种方式解决它:

Field someField = someClass.getDeclaredField("fieldname");
someField.setAccessible(true);
Object val = someField.get(someObj);

但这是应该使用什么反射,一般来说是一个你不应该使用的相当丑陋的解决方案。除此之外,这些操作相当昂贵。您应该简单地为所需字段实现getter方法。如果你需要使用上面的解决方案,你应该考虑重新设计完整的东西,因为这远离干净的OOP。