在静态上下文中,为什么不能调用getClass()
的静态版本(而不是必须使用my.package.name.MyClassName.class
)?
编译器是否足够聪明,无法确定何时使用对象方法+何时使用静态方法?
为清晰起见,请注意:
我不是说static getClass()
应该使用代替非静态方法getClass()
(这很明显 - 如果SpecialFoo
是Foo
的子类,然后getClass()
的{{1}}可以返回Foo
或Foo.class
或其他内容,并且必须在运行时确定它。
我说我想知道为什么不存在两个版本的SpecialFoo.class
,一个是静态方法,只适用于静态上下文,而常规非静态方法getClass()
。如果不可能,那就不可能了,那就是答案。如果它可能但是还没有完成,那么这是一个历史选择,也许这是一个很好的理由。这就是我想知道的。
宣布
会很棒getClass()
而不是
final static Logger logger = LoggerFactory.getLogger(getClass());
前者可以从一个类逐字复制到下一个类,而后者则要求你在每个文件中复制类名。
答案 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
在编译时已知(已解决)。该方法在运行时没有合理的事情;你必须做一些编译魔术,以便在编译时实际解决该方法调用的结果。