试探性的解释,尽管不可否认它并不完全正确。对于任何课程C
,当你这样做时:
final C c = new C();
Object
这里涉及两个:Class<C>
对象(通过上下文类加载器提供)和c
实例。将通过其方法(在 中定义)c
知道它是哪个类。.getClass()
Object
new
关键字能够建立正确的“反向链接”这一事实Class
是 JVM 实现的责任。虽然 JLS 中肯定提到了这一点,但我不知道在哪里......
现在,更重要的是。
如果您有一个方法声明为:
synchronized void whatever() { someCode(); }
那么它大致相当于(为什么大致:见下文):
void whatever()
{
synchronized(this) {
someCode();
}
}
也就是说,此代码在实例级别同步。
但是,如果该方法是静态的,则:
public static synchronized void meh() { someOtherCode(); }
大致相当于(为什么大致:见下文):
public static void meh()
{
synchronized(getClass()) {
someOtherCode();
}
}
需要注意的一点是,所有Class
对象都是单例;无论C
您创建多少类实例,.getClass()
都将始终返回相同的Class
对象。尝试这个:
public static void main(final String... args)
{
final String s1 = "foo";
final String s2 = "bar";
System.out.println(s1.getClass() == s2.getClass()); // true
}
getClass()
添加相当于的事实,this.getClass()
您就得到了图片。Class
本身是一个Object
,它遵守 any 的监控规则Object
。
而且由于这里我们总是引用完全相同的对象,因此应用了监控规则;)
现在,“大致”:在上面编写的代码中,逻辑是相同的;但是,根据您编写该代码的方式,字节码可能会有所不同;但 JIT 将有自己的发言权,并最终会优化代码路径。