![](/img/trans.png)
[英]What is the best way to called non-static method from static method in java?
[英]In Java, inside a static method, what is the way to determine which class the static method was called on?
假设您在Java中有一个类和一个子类:
public abstract class Car {
public static Car getCar() {
Car car = makeCar();
return car;
}
private static Car makeCar() {
//bunch of code that makes the car
return car;
}
}
public class Ferrari extends Car {
private static makeCar() {
//bunch of code that makes a Ferrari! Yeah!
awesomeRide = new Car();
return awesomeRide;
}
}
然后在另一个类中调用:
Ferrari.getCar();
法拉利超类的getCar() 和 makeCar()方法将被调用。 法拉利不能@Override getCar(),因为在Java中,静态方法不能被覆盖。
因此,在Car的getCar()方法中,如何确定该方法调用是否发送给了Ferrari类而不是Car类呢? 由于这是一个静态方法,因此我显然不能执行if(this instanceOf Car)
。
编辑:正确的答案(如下)告诉我,实际上我无法从Car内得知由于有人调用Car.getCar()或Ferrari.getCar()而正在运行getCar()。
但是我不知道的是,根据Java的文档,虽然Java中不能覆盖静态方法,但可以将其隐藏 。
隐藏和覆盖之间的主要区别在于,通过隐藏,静态方法在同一类上调用其他静态方法,而不是从其路由的子类。
这意味着重写后,如果这些不是静态方法,则只要调用方调用myFerrariInstance.getCar(),法拉利的makeCar()始终会从Car的getCar()方法中调用。 但是,通过隐藏,法拉利的makeCar()将永远不会从Car的getCar()方法中调用, 因为makeCar()也是同一类上的静态方法。
因此,在Car的getCar()方法中,如何确定该方法调用是否发送给了Ferrari类,而不是Car类
你不能 (我以为javac
曾经为两个调用生成相同的字节码-现在不会了,但是我不相信有任何方法可以检测到在执行时进行了哪个调用,并且即使它仍然存在,我也不会感到惊讶在JITting期间丢失了该信息。)
如果您认为需要这样做,则应该更改设计-进行重大更改,或仅将相关类作为方法的参数传递。
您可以给每个子类一个具有相同签名的静态方法。 这不会被覆盖,但是会起作用-您最终将调用正确的方法,然后该方法可以执行您想要的操作。 但是,如果您创建了一个新的子类并忘记添加该方法,它将只是默默地调用超类。
仅有一个实际方法,因此无法知道在源中指定的类(不阅读源)。您可以做的是隐藏原始方法,尽管通常这是一个坏主意。
如果要使用该类创建该类型的汽车,则可以使用构造函数
Car car = new Ferrari();
如前所述,尚不清楚您要实现什么目标,也许您应该重新设计代码。
类似于您的代码(据我了解),将是这样的:
Ferrari ferrari = Car.create(Ferrari.class);
可以通过以下简单示例实现:
/**
* @author ben
*/
public class TestClass
{
public abstract static class Car<E> {
private Car() {}
protected abstract void build();
@Override
public String toString() {
return getClass().getSimpleName();
}
public static <E extends Car> E create(Class<E> p_class) throws Exception {
E car = p_class.newInstance();
car.build();
return car;
}
}
public static class Ferrari extends Car<Ferrari> {
protected Ferrari(){};
@Override
protected void build() {
//your bunch of code ...
}
}
public static class Mercedes extends Car<Mercedes> {
protected Mercedes(){};
@Override
protected void build() {
//your bunch of code ...
}
}
public static void main(String[] args) throws Exception {
Ferrari ferrari = Car.create(Ferrari.class);
Mercedes mercedes = Car.create(Mercedes.class);
System.out.println("CAR1:" + ferrari);
System.out.println("CAR2:" + mercedes);
}
}
但是还有许多其他方式...
如前所述,尚不清楚您要做什么。
干杯。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.