2009-10-02 32 views
2

考虑这个Java代码Java中,获取Class对象包含类,而不是运行时类

class A{ 
//@returns Class object this method is contained in 
// should be A in this case 
public Class<?> f() { 
    return getClass(); 
} 
} 

class B extends A {} 

B b = new B(); 

System.out.println(b.f()); 
//output -- B.class (Wrong, should be A.class) 

f()我不能使用getClass(),因为这会给我runtype,这是B。我正在寻找一种方式来获得classf()Class对象内(不提A明确,明显)

+4

你为什么不明确提及A? 'A.class'似乎是最直接的解决方案。 – 2009-10-02 01:27:10

+0

我想如果你必须弄清楚你的实例在运行时的确切类型,就会给出一个强烈的信号,指出需要重构或重新思考。 – aberrant80 2009-10-02 04:04:39

回答

4

您可以使用异常堆栈跟踪设施,做这样的事情:

public String f() { 
    Exception E = new Exception(); 
    E.fillInStackTrace(); 
    return E.getStackTrace()[0].getClassName(); // load it if you need to return class 
} 
+0

不错,这真的很巧 – Mike 2009-10-02 00:59:42

+4

你不需要异常来获取堆栈跟踪。这是更好的方法:Thread.currentThread()。getStackTrace()。 – 2009-10-02 01:03:22

+3

其实,这是行不通的。 Thread.currentThread()。getStackTrace()使用Thread自己的方法(dumpThreads()和getStackTrace())自己填充堆栈跟踪,尽管它可能根据JVM版本/实现而有所不同。 – ChssPly76 2009-10-02 01:26:10

1

你可以使用

class.getMethod("f",parameterTypes).getDeclaringClass() 
+0

这只适用于公共方法;加上它处理参数相当麻烦。 – ChssPly76 2009-10-02 01:04:31

+0

你是对的。使用堆栈跟踪的方法可能会更好。当然它应该是getClass(固定的)。然而,f不必是最终的。为什么它需要成为? – sleske 2009-10-02 12:47:20

2

我不得不说,简单地返回A.class就像@mmyers建议的那样简单得多。如果实际上并不需要运行时值,那么在运行时试图派生它就没有多大意义。唯一出现的问题是,如果您重构类的名称,而另一个具有相同名称的恰好存在于同一个包中。

为了清晰起见,我会在现在考虑这个机会。

+0

没错。派生的答案是过于复杂的事情。 – aberrant80 2009-10-02 04:02:52

6

new Object() {}.getClass().getEnclosingClass()。但请不要!

+0

现在是切肉刀! – Yishai 2009-10-02 02:03:12

+0

是的,我从别人那里学到了。 – 2009-10-02 02:07:47

1

我知道你说你不想说的A.class明确

class A {   
    public Class<?> f() { 
     return A.class; 
    } 
} 

,但我在努力寻找一个使用情况下上面的代码是不能令人满意的。

相关问题