繁体   English   中英

在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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM