5

我有两个这样定义的类:

class A {
    public static String getName(){
        Class c = getCalledClass();
        return c.getSimpleName();
    }
}

class B extends A {
    //no methods are defined here!
}

我想知道是否可以编写static方法以getCalledClass()使调用A.getName()返回AB.getName()返回B

谢谢。

4

4 回答 4

7

这是不可能的,至少在你所问的一般意义上是不可能的。

没有办法。_ B.getName()虽然您可以在代码中键入它,但它会被编译为相同的字节码A.getName()(我认为您也会收到编译器警告)。

因此在运行时,没有办法知道某人是如何引用静态方法的——就像没有办法知道调用者正在使用什么局部变量名一样。

于 2013-07-05T11:56:59.050 回答
0

我不知道您是否可以根据您的要求删除静态。如果您可以删除静态并使用多态性,那么您可以获得您想要的。下面是我测试的代码示例。

class A {
    public String getName(){
        Class c = this.getCalledClass();
        return c.getSimpleName();
    }

    Class getCalledClass() {        
        return A.class;
    }
}

class B extends A {
    Class getCalledClass() {
        return B.class;
    }
}

class TestApplication {
    public static void main(String[] args) {
        A objA = new A();
        System.out.println(objA.getName());

        A objB = new B();
        System.out.println(objB.getName());
    }
}
于 2013-07-05T11:52:18.763 回答
0

堆栈跟踪将仅包含定义该静态方法的类的名称。即使您调用B.method(),您也会A.method()在堆栈跟踪中看到。使用静态方案,您无法可靠地提取所需的信息。

如果您使用非静态方法,那么this将是您正在寻找的类型的实例。

public String getName() {
  return this.class.getSimpleName();
}
于 2013-07-05T11:52:58.220 回答
0

当 javac 编译器找到对 的调用时B.getName(),它会立即将其解析为并在字节码中A.getName()放置一个静态调用。A.getName()

java中不存在任何机制可以从字节码中推断出源代码中使用的形式。

如果你想B.getName()成为一个不同的方法A.getName(),你必须定义一个调用getName()in的方法B。由于在该方法中被调用的类将始终为“B”,因此无需弄乱堆栈跟踪或其他机制。但是,通常如果您认为点之前的内容很重要,则可能有更好的面向对象设计供您使用。

于 2013-07-05T12:00:48.320 回答