在Java中,静态方法内部,如何判断调用了哪个class静态方法?
In Java, inside a static method, what is the way to determine which class the static method was called on?
假设您在 Java 中有一个 class 和一个子 class:
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;
}
}
然后在另一个class中你调用:
Ferrari.getCar();
Ferrari 的 super-class 的 getCar() 和 将调用 makeCar() 方法。 Ferrari 不能@Override getCar() 因为在 Java 中,静态方法不能被覆盖。
那么在 Car 的 getCar() 方法中,我如何判断方法调用是发送给 class Ferrari,而不是 class,Car?由于它是一个静态方法,我显然不能做 if(this instanceOf Car)
。
编辑:正确答案(下方)向我表明,我确实无法从 Car 中判断 getCar() 是否由于有人呼叫而处于 运行 Car.getCar() 或 Ferrari.getCar()。
但我不知道的是,根据 Java 的文档,虽然在 Java 中不能覆盖静态方法,但可以 隐藏.
隐藏和覆盖之间的主要区别在于,通过隐藏,静态方法会调用同一class上的其他静态方法,而不是子class他们被路由进来。
这意味着通过覆盖,如果这些不是静态方法,法拉利的 makeCar() 总是会在调用者调用 myFerrariInstance.getCar() 的任何时候从 Car 的 getCar() 方法调用。然而,通过隐藏,Ferrari 的 makeCar() 将永远不会从 Car 的 getCar() 方法中调用,因为 makeCar() 也是同一 class.[=15 上的静态方法=]
So in the Car's getCar() method, how can I tell whether the method call was sent to the class Ferrari, as opposed to the class, Car
你不能。 (我认为 javac
使用 为两个调用生成相同的字节码 - 现在没有,但我不相信有任何方法可以检测哪个调用是在执行时间,如果它在 JIT 期间仍然丢失该信息,我不会感到惊讶。)
如果您觉得 需要 这样做,您应该改变设计 - 要么显着改变,要么只是将相关的 class 作为参数传递给方法.
您可以为您的每个子class提供一个具有相同签名的静态方法。这不会是最重要的,但它会起作用——你最终会调用正确的方法,然后它可以做你想做的事。但是如果你创建了一个新的 subclass 而忘记了添加方法,它会默默地调用 superclass one...
只有一个实际方法,因此无法知道您在源代码中指定了哪个 class(无需阅读源代码)您可以做的是隐藏原始方法,尽管这通常是一个坏主意。
如果您想使用 class 来创建该类型的汽车,您可以使用构造函数
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);
}
}
但是还有很多其他的方法...
如题,不清楚你要做什么
干杯。
假设您在 Java 中有一个 class 和一个子 class:
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;
}
}
然后在另一个class中你调用:
Ferrari.getCar();
Ferrari 的 super-class 的 getCar() 和 将调用 makeCar() 方法。 Ferrari 不能@Override getCar() 因为在 Java 中,静态方法不能被覆盖。
那么在 Car 的 getCar() 方法中,我如何判断方法调用是发送给 class Ferrari,而不是 class,Car?由于它是一个静态方法,我显然不能做 if(this instanceOf Car)
。
编辑:正确答案(下方)向我表明,我确实无法从 Car 中判断 getCar() 是否由于有人呼叫而处于 运行 Car.getCar() 或 Ferrari.getCar()。
但我不知道的是,根据 Java 的文档,虽然在 Java 中不能覆盖静态方法,但可以 隐藏.
隐藏和覆盖之间的主要区别在于,通过隐藏,静态方法会调用同一class上的其他静态方法,而不是子class他们被路由进来。
这意味着通过覆盖,如果这些不是静态方法,法拉利的 makeCar() 总是会在调用者调用 myFerrariInstance.getCar() 的任何时候从 Car 的 getCar() 方法调用。然而,通过隐藏,Ferrari 的 makeCar() 将永远不会从 Car 的 getCar() 方法中调用,因为 makeCar() 也是同一 class.[=15 上的静态方法=]
So in the Car's getCar() method, how can I tell whether the method call was sent to the class Ferrari, as opposed to the class, Car
你不能。 (我认为 javac
使用 为两个调用生成相同的字节码 - 现在没有,但我不相信有任何方法可以检测哪个调用是在执行时间,如果它在 JIT 期间仍然丢失该信息,我不会感到惊讶。)
如果您觉得 需要 这样做,您应该改变设计 - 要么显着改变,要么只是将相关的 class 作为参数传递给方法.
您可以为您的每个子class提供一个具有相同签名的静态方法。这不会是最重要的,但它会起作用——你最终会调用正确的方法,然后它可以做你想做的事。但是如果你创建了一个新的 subclass 而忘记了添加方法,它会默默地调用 superclass one...
只有一个实际方法,因此无法知道您在源代码中指定了哪个 class(无需阅读源代码)您可以做的是隐藏原始方法,尽管这通常是一个坏主意。
如果您想使用 class 来创建该类型的汽车,您可以使用构造函数
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);
}
}
但是还有很多其他的方法...
如题,不清楚你要做什么
干杯。