我有一个类库,我没有编写,它定义了几个具有静态方法的类和子类。一个非常简单的例子:
public class Vehicle {
static String getName() { return "unknown"; }
}
public class Car extends Vehicle {
static String getName() { return "car"; }
}
public class Train extends Vehicle {
static String getName() { return "train"; }
}
现在,我有一个物体,它是一辆车,可能是汽车或火车,并且想要调用它的getName()函数。再次,非常剥离:
public class SMCTest {
public static void main(String[] args) {
Vehicle vehicle=new Car();
System.out.println(vehicle.getName());
}
}
这打印"未知"而不是#34; car",因为JVM不需要或使用该对象来调用静态方法,它只是使用该类。
如果这是我的代码,我会重写车辆库以使用单例和非静态方法,但因为它不是我的代码,所以我宁愿不接触它。
有没有办法调用"真实"的静态方法?对象的类,最好不使用反射?如果有帮助,我可以将上面示例中的vehicle
更改为Class <? extends Vehicle>
变量并使用它,但我不知道这有助于我避免反思。
答案 0 :(得分:5)
最好不使用反射?
删除该要求,并且:
vehicle.getClass().getMethod("getName").invoke(null);
可以解决问题。
(但是,您应该修复代码。)
答案 1 :(得分:1)
如果您了解所涉及的所有课程,则无需反思。使用java 8(为较低版本的Java创建必要的接口和(匿名)类):
public class VehicleUtil {
private static final Map<Class<? extends Vehicle>, Supplier<String>> map = createMap();
private static Map<Class<? extends Vehicle>, Supplier<String>> createMap() {
Map<Class<? extends Vehicle>, Supplier<String>> result = new HashMap<>();
result.put(Vehicle.class, Vehicle::getName);
result.put(Car.class, Car::getName);
result.put(Train.class, Train::getName);
return result;
}
public static String getName(Vehicle vehicle) {
return map.get(vehicle.getClass()).get();
}
public static void main(String[] args) {
System.out.println(VehicleUtil.getName(new Vehicle()));
System.out.println(VehicleUtil.getName(new Car()));
System.out.println(VehicleUtil.getName(new Train()));
}
}
以上只是一种更优雅的方式:
public static String getName(Vehicle vehicle) {
return Vehicle.class.equals(vehicle.getClass()) ? Vehicle.getName()
: Car.class.equals(vehicle.getClass()) ? Car.getName()
: Train.class.equals(vehicle.getClass()) ? Train.getName()
: null;
}