为什么getClass()不能作为静态方法使用?
在静态上下文中,为什么不能调用getClass()
的静态版本(而不是必须使用my.package.name.MyClassName.class
)?
难道编译器不够聪明,无法确定何时使用对象方法+何时使用静态方法?
注意清楚:
我不是说应该使用static getClass()
而不是非静态方法getClass()
(这很明显 – 如果SpecialFoo
是Foo
的子类,那么Foo
的getClass()
可以返回Foo.class
或SpecialFoo.class
或其他东西,必须在运行时确定)。
我说我想知道为什么没有两个版本的getClass()
,一个是静态方法,只适用于静态上下文,而常规非静态方法getClass()
。 如果不可能,那就不可能了,那就是答案。 如果它可能但尚未完成,那么这是一个历史选择,也许这是一个很好的理由。 这就是我想知道的。
宣布这将是伟大的
final static Logger logger = LoggerFactory.getLogger(getClass());
代替
final static Logger logger = LoggerFactory.getLogger(my.package.name.MyClass.class);
前者可以从一个类逐字复制到下一个类,而后者则要求您在每个文件中复制类名。
如果没有别的,因为同时拥有方法的static
和非static
版本(可能因为它是合法的,如果不鼓励,在非static
上下文中调用static
方法)是不合法的。
我也觉得这样的方法,虽然在定义记录器或其他任何东西的上下文中很有用,但在其他上下文中可能会令人困惑,例如从实例方法调用时。
你可以用这个成语
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 } }
每个对象都是Java中的类的实例,没有类可以是另一个类的实例! 这就是为什么getClass()不是静态的,因为它只在对象的上下文中有意义:你试图找到一个对象是什么类的实例。 如果它是一个静态函数,它可以在一个对象外部调用 – 但写入没有意义
String.getClass()
因为你已经知道你在“问”String类!
getClass()提供了与静态.class不同的function。 它用于获取调用它的实例的运行时类。
Object o = new String(); o.getClass() // returns Class Object.class // returns Class
因为如果getClass()
是静态的,那么它的代码必须在一个类中定义 – 可能是Object
。 在那里,您无法确定调用者类,也没有调用它的对象实例。
编辑:
这不是名字; 它可能非常好getClass2()
。 我是说如果你定义一个静态方法,你就无法知道调用它的类:
public class Object { public static Class> getClass2() { return ...? } }
你可以自己实现一个。 获取堆栈跟踪,找到调用者类。
实际上,logger lib可以自己实现
static Logger logger = LoggerFactory.getLogger(); // auto detect caller class
静态getClass()
方法不会返回类对象,包含该对象的变量的类来自哪个类? 这将改变getClass()
的语义。 例:
Interface foo = new FooImpl(); foo.getClass(); // returns Class because the runtime type is FooImpl. // If getClass() was static, it would return Class.
除了其他答案(这解释了为什么我们不能使用与非静态’getClass()’方法相同的签名创建静态方法),人们会想知道是否可以拥有,比如static Class getStaticClass()
因此,例如String.getStaticClass()
将等同于String.class
。 但是,再次,这种方法不能成为“正常”的方法在哪里定义? 在对象? 那么当它被称为String.getStaticClass()或Object.getStaticClass()时,这个单一方法将如何知道返回什么(String.class或Object.class)? 它会在运行时决定吗? 没门。
静态方法没有意义,因为String.class
在编译时已知(已解决)。 该方法在运行时没有合理的事情; 你必须做一些编译魔术,以便在编译时实际解决该方法调用的结果。