繁体   English   中英

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

[英]Accessing super class's hidden fields while using reflection

由于无法解释问题,因此我将通过一个示例进行说明。

让我们上两节课,如下

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

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

现在,我想同时获得Vehicle和Audi系列。 所以我可以用

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"

这是我的问题:但是,如果在编译过程中我无法访问VehicleAudi类,并且只能使用反射来获取对象,那么如何获得vehicle's series

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));

输出: A8

无论如何,是否可以通过上述方法获得“ Vehicle类别” series字段“ Sedan”

PS:我无法更改设计来避免此问题。

我很惊讶,您可以通过仅将ist投射到车辆上来访问车辆领域。

您的方法有效,只需使用“车辆类别”中的“字段”进入最后一步:

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();

如果您可以在超类中添加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;
    }
}

可以这样解决:

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

但这不是反射应该被使用的,通常来说,您不应该使用一个相当丑陋的解决方案。 除此之外,这些操作相当昂贵。 您应该只为必填字段实现一种getter方法。 如果您需要使用上述解决方案,则应考虑重新设计完整的东西,因为这与干净的OOP相去甚远。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM