getClass()方法在Java API中定义为:
public final native Class<?> getClass();
但是,我看到其他人的代码是这样的,并且有效:
private final Log logger = LogFactory.getLog(getClass());
我尝试在我自己的代码中使用上述行,然后我收到了这个投诉:
"Can't make a static reference from a non-static method() from the type Object"
它应该是objectName.getClass(),对吗?我想知道为什么'记录器'定义是有效的。
答案 0 :(得分:3)
getClass
不是静态的,因此从静态上下文中使用MyClass.class
语法,并从非静态上下文中使用getClass()
语法:
public class MyClass {
public Logger getLogger() { return LogFactory.getLog(getClass()); }
public static Logger getLogger() { return LogFactory.getLog(MyClass.class); }
}
答案 1 :(得分:2)
如果它是private final
而不是private static final
则有效,因为如果它是private final
则为特定对象分配;它隐含地等同于LogFactory.getLog(this.getClass())
。
答案 2 :(得分:1)
字段声明如下:
modifiers type name = initializer;
其中一个可能的修饰符是static
。这是一个非常重要的修饰符 - 静态字段属于类。在创建任何实际对象之前,在加载类时创建并初始化它。只需使用Classname.name
。
如果该字段不是静态的,则在创建对象时创建并初始化该字段,就在构造函数中运行代码之前。
这意味着静态字段的初始化程序在类创建时运行,没有任何类的实例,而在创建实例后运行非静态字段的初始化程序。因此,当运行静态字段的初始化程序时,您没有this
,并且您不能使用非静态方法,这些方法需要this
来运行。
因此,您无法在静态上下文中运行getClass()
。它应该转到this
对象,并运行本机代码,该代码在给定对象的情况下获取对与其关联的class
对象的引用。没有对象,你就无法运行它。
但是在静态初始化时你可以使用一个类文字。因此,如果您的班级名为Foo
,则可以使用Foo.class
。那是一个文字。
如果您希望您的记录器是静态的(一个记录器,由该类的所有实例共享,在该类的任何实例存在之前创建),那么您需要将它传递给类文字。
private static final Log logger = LogFactory.getLog(Foo.class);
如果您希望每个实例都有自己的记录器对象,则需要删除static
修饰符,并使用给定示例中的代码。