【发布时间】:2016-06-20 00:41:41
【问题描述】:
我有一个类库,不是我写的,它定义了几个类和子类,它们有静态方法。一个非常精简的例子:
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());
}
}
这会打印“unknown”,而不是“car”,因为 JVM 不需要或不使用对象来调用静态方法,它只使用类。
如果那是我的代码,我会重写车辆库以使用单例和非静态方法,但由于它不是我的代码,我宁愿不碰它。
有什么方法可以调用对象的“真实”类的静态方法,最好不使用反射?如果有帮助,我可以将上面示例中的 vehicle 更改为 Class <? extends Vehicle> 变量并使用它,但我看不出这如何帮助我避免反射。
【问题讨论】:
-
是的,有。您可以简单地向下转换对象
vehicle,因为您已经知道它的具体类:Car vehicle = new Car();。然后vehicle.getName()将返回car。然而,这样做会导致警告,因为您不应该通过实例访问静态方法。 -
您似乎希望静态方法以多态方式运行。这是不可能的。使用对象调用静态方法显示了一个应该解决的设计问题。静态方法应该是实例方法。
-
@aribeiro:在这个精简的示例中,我知道对象实际上是一辆汽车。在我想在现实世界中做的事情中,我得到了一个从其他地方传递过来的对象,我不知道它到底是什么。所以我不能只使用 Car 类。我想让示例尽可能简短/简单。
-
@JBNizet:我知道存在设计问题。但是由于“Vehicle”类库不是我的,我宁愿绕过它,也不愿花几周时间与该库的创建者争夺一个固定版本,或者花几天时间自己修复它并创建一个我不能的分支得到更新。
-
是的,反思似乎是唯一的方法。 @Joe 给出了如何做的答案。
标签: java