在Java中,在静态方法中,确定调用静态方法的类的方法是什么?

时间:2016-03-24 20:54:11

标签: java class subclass

假设您在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()方法中,如何判断方法调用是否发送到法拉利类,而不是类Car?由于它是一种静态方法,我显然不能if(this instanceOf Car)

编辑:正确的答案(下面)告诉我,如果由于有人调用Car.getCar()或法拉利而运行getCar(),我确实无法从Car 中告诉 .getCar()。

但我不知道的是,根据Java的文档,虽然静态方法无法在Java中覆盖,但它可以隐藏

隐藏和覆盖之间的关键区别在于,隐藏时,静态方法在同一个类上调用其他静态方法,而不是它们从中路由的子类。

这意味着,如果这些不是静态方法,那么无论何时调用者调用myFerrariInstance.getCar(),法拉利的makeCar()总是会被Car的getCar()方法调用。然而,隐藏起来,法拉利的makeCar()将永远不会被Car的getCar()方法调用,因为makeCar()也是同一类的静态方法。

3 个答案:

答案 0 :(得分:8)

  

所以在Car的getCar()方法中,如何判断方法调用是否发送到法拉利类,而不是类,Car

你不能。 (我认为javac 使用为两个调用生成相同的字节码 - 它现在没有,但我不相信有任何方法可以检测哪个电话是在执行时发出的,如果在JITting期间它仍然丢失了这些信息,我不会感到惊讶。)

如果你觉得你需要这样做,你应该改变设计 - 要么显着改变,要么只是将相关的类作为参数传递给方法。

可以为每个子类提供一个具有相同签名的静态方法。这不会是最重要的,但它会起作用 - 你最终会调用正确的方法,然后可以做你想要的。但是如果你创建了一个新的子类并且忘了添加方法,它就会默默地调用超类... ...

答案 1 :(得分:0)

只有一个实际的方法,所以无法知道你在源代码中指定了哪个类(没有阅读源代码)你可以做的是隐藏原始方法,虽然这通常是一个坏主意。

如果您想使用该类创建该类型的汽车,您可以使用构造函数

Car car = new Ferrari();

答案 2 :(得分:0)

如前所述,目前尚不清楚您想要实现什么,也许您应该重新设计代码。

与您的代码类似(据我所知),类似于:

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

但是还有很多其他的方式...... 如上所述,目前尚不清楚你想做什么。

干杯。