Java:从静态方法获取被调用的类名

时间:2013-07-05 11:21:11

标签: java reflection

我有两个类定义如下:

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()将返回{{} 1}}?

感谢。

4 个答案:

答案 0 :(得分:6)

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

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

因此在运行时,没有办法告诉某人是如何引用静态方法的 - 就像没有办法告诉调用者使用的局部变量名一样。

答案 1 :(得分: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());
    }
}

答案 2 :(得分:0)

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

如果您使用非静态方法,则this将是您要查找的类型的实例。

public String getName() {
  return this.class.getSimpleName();
}

答案 3 :(得分:0)

当javac编译器找到对B.getName()的调用时,它会在那里将其解析为A.getName()并在字节代码中对A.getName()进行静态调用。

java中没有任何机制可以从字节代​​码中推断出源代码中使用的形式。

如果您希望B.getName()成为与A.getName()不同的方法,则必须在getName()中定义名为B的方法。因为在那个方法中被调用的类总是'B',所以不需要乱用堆栈跟踪或其他机制。但是,一般来说,如果您认为点之前的内容很重要,那么可能会有一个更好的面向对象设计供您使用。