如何理解Object.getClass()方法?

Rya*_*nqy 6 java

Java Object.getClass()方法javadoc说:

返回此运行时类Object.返回的Class对象是由static synchronized所表示的类的方法锁定的对象.实际结果的类型是Class<? extends |X|> 其中|X|是静态类型上其表达的擦除 getClass被调用.例如,此代码片段中不需要强制转换:

Number n = 0; 
Class<? extends Number> c = n.getClass();
Run Code Online (Sandbox Code Playgroud)

返回:Class表示此对象的运行时类的对象.

什么是运行时类?

"返回的Class对象......被static synchronized方法锁定"是什么意思?

T.J*_*der 7

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.classClass加载Foo类的实例.)

因此,当线程1进入同步块时,如果线程2尝试进入该块(或其他任何同步的块Foo.class),则必须等待.

它不必是对同一方法的两次调用; 我可以有两个static synchronized方法(m1m2),其中线程1正在调用m1而线程2正在调用m2,并且调用m2必须等待调用m1完成,因为它们都在同一个实例上同步(Class实例为Foo) .

这与此getClass()有何关系?因为同样的Class实例就是getClassFoo实例返回:

System.out.println(Foo.class == (new Foo()).getClass()); // true
Run Code Online (Sandbox Code Playgroud)