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

但是还有很多其他的方法...
如题,不清楚你要做什么

干杯。