为什么getClass()不能作为静态方法使用?

时间:2011-04-20 16:15:22

标签: java static

在静态上下文中,为什么不能调用getClass()的静态版本(而不是必须使用my.package.name.MyClassName.class)?

编译器是否足够聪明,无法确定何时使用对象方法+何时使用静态方法?


为清晰起见,请注意:

我不是说static getClass()应该使用代替非静态方法getClass()(这很明显 - 如果SpecialFooFoo的子类,然后getClass()的{​​{1}}可以返回FooFoo.class或其他内容,并且必须在运行时确定它。

我说我想知道为什么不存在两个版本的SpecialFoo.class,一个是静态方法,只适用于静态上下文,而常规非静态方法getClass()。如果不可能,那就不可能了,那就是答案。如果它可能但是还没有完成,那么这是一个历史选择,也许这是一个很好的理由。这就是我想知道的。

宣布

会很棒
getClass()

而不是

final static Logger logger = LoggerFactory.getLogger(getClass());

前者可以从一个类逐字复制到下一个类,而后者则要求你在每个文件中复制类名。

8 个答案:

答案 0 :(得分:26)

你可以使用这个习语

    Class<?> cl=new Object(){}.getClass().getEnclosingClass();

例如:

static class Bar {
    public static void main(String[] args) {
        Class<?> cl=new Object(){}.getClass().getEnclosingClass();
        System.out.println(cl==Bar.class);  //will print true
    }
}

答案 1 :(得分:7)

每个对象都是Java中的类的实例,没有类可以是另一个类的实例!这就是为什么getClass()不是静态的,因为它只在对象的上下文中有意义:你试图找到一个对象是什么类的实例。 如果它是一个静态函数,它可以在一个对象外部调用 - 但是编写

是没有意义的
String.getClass()

因为你已经知道你在“询问”String类!

答案 2 :(得分:5)

getClass()提供了与静态.class不同的功能。它用于获取调用它的实例的运行时类。

Object o = new String();
o.getClass() // returns Class<String>    
Object.class // returns Class<Object>

答案 3 :(得分:3)

如果没有别的,因为同时拥有static和非static版本的方法是不合法的(可能是因为如果不鼓励,调用{{1}是合法的非static上下文中的方法。)

我也觉得这样的方法,虽然在定义记录器或其他任何事物的上下文中很有用,但在其他上下文中可能会混淆,例如从实例方法调用时。

答案 4 :(得分:2)

因为如果getClass()是静态的,那么它的代码必须在一个类中定义 - 可能是Object。在那里,您无法确定调用者类,并且没有调用它的对象实例。

编辑:

这不是名字;它可能非常好getClass2()。我是说如果你定义一个静态方法,你就无法知道调用它的类:

public class Object {

    public static Class<?> getClass2() {
        return ...?
    }

}

答案 5 :(得分:2)

您可以自己实施一个。获取堆栈跟踪,找到调用者类。

实际上,记录器lib本身可以实现

static Logger logger = LoggerFactory.getLogger(); // auto detect caller class

答案 6 :(得分:1)

静态getClass()方法不会返回类对象中包含该对象的变量的类吗?这会改变getClass()的语义。例如:

Interface foo = new FooImpl(); 
foo.getClass(); // returns Class<FooImpl> because the runtime type is FooImpl. 
                // If getClass() was static, it would return Class<Foo>.

答案 7 :(得分:1)

除了其他答案(这解释了为什么我们不能使用与非静态'getClass()'方法相同的签名制作静态方法),人们会怀疑它是否可能有,比如说{ {1}}例如,static Class getStaticClass()等同于String.getStaticClass()。但是,同样,这种方法不能成为“正常”方法,它将在何处定义?在对象?那么当它被称为String.getStaticClass()或Object.getStaticClass()时,这个单一方法如何知道返回什么(String.class或Object.class)?它会在运行时决定吗?没门。

静态方法没有意义,因为String.class在编译时已知(已解决)。该方法在运行时没有合理的事情;你必须做一些编译魔术,以便在编译时实际解决该方法调用的结果。