Java Object.getClass()方法javadoc说:
返回此运行时类
Object.返回的Class对象是由static synchronized所表示的类的方法锁定的对象.实际结果的类型是Class<? extends |X|>其中|X|是静态类型上其表达的擦除getClass被调用.例如,此代码片段中不需要强制转换:Run Code Online (Sandbox Code Playgroud)Number n = 0; Class<? extends Number> c = n.getClass();返回:
Class表示此对象的运行时类的对象.
什么是运行时类?
"返回的Class对象......被static synchronized方法锁定"是什么意思?
getClass在运行时为您Class提供对象实际类的实例,而不是您对它的引用类型.
一个简单的例子可能会澄清.假设我们有一个方法接受任何实现List和转储其类名的东西;
static void foo(List l) {
System.out.println(l.getClass().getName());
}
Run Code Online (Sandbox Code Playgroud)
我们可以使用各种不同类型的列表来调用它:
foo(new LinkedList()); // Outputs "java.util.LinkedList"
foo(new ArrayList()); // Outputs "java.util.ArrayList"
Run Code Online (Sandbox Code Playgroud)
因为foo可以在任何List情况下调用它,在罕见的(!)情况下它是不可避免的,它可以用来计算getClass它给出的实例的实际类.
如何理解返回的Class对象是否被静态同步方法锁定?
static synchronized方法的实例上的方法同步Class表示在运行时加载的类,因此对这些方法的调用不能重叠.假设我有一个类,Foo使用静态方法notThreadSafe,我有两个线程需要调用它:
// On thread 1
Foo.notThreadSafe();
// On thread 2
Foo.notThreadSafe();
Run Code Online (Sandbox Code Playgroud)
因为它不是线程安全的,所以notThreadSafe会声明synchronized:
public static synchronized void notThreadSafe() {
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
这实际上是一样的
public static void notThreadSafe() {
synchronized (Foo.class) {
/* ... */
}
}
Run Code Online (Sandbox Code Playgroud)
(Foo.class是Class加载Foo类的实例.)
因此,当线程1进入同步块时,如果线程2尝试进入该块(或其他任何同步的块Foo.class),则必须等待.
它不必是对同一方法的两次调用; 我可以有两个static synchronized方法(m1和m2),其中线程1正在调用m1而线程2正在调用m2,并且调用m2必须等待调用m1完成,因为它们都在同一个实例上同步(Class实例为Foo) .
这与此getClass()有何关系?因为同样的Class实例就是getClass在Foo实例返回:
System.out.println(Foo.class == (new Foo()).getClass()); // true
Run Code Online (Sandbox Code Playgroud)