簡體   English   中英

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

[英]How to understand the Object.getClass() method?

Java Object.getClass()方法javadoc說:

返回此Object的運行時類。 返回的Class對象是由所表示的類的static synchronized方法鎖定的對象。 實際的結果類型是Class<? extends |X|> Class<? extends |X|> where |X| 是調用getClass的表達式的靜態類型的擦除。 例如,此代碼片段中不需要強制轉換:

 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());
}

我們可以使用各種不同類型的列表來調用它:

foo(new LinkedList()); // Outputs "java.util.LinkedList"
foo(new ArrayList());  // Outputs "java.util.ArrayList"

因為foo可以用任何List調用,所以在罕見的(!)情況下它是不可避免的,它可以使用getClass來計算它給出的實例的實際類。

如何理解返回的Class對象是否被靜態同步方法鎖定?

static synchronized方法在Class的實例上同步,該類在運行時表示已加載的類,因此對此類方法的調用不能重疊。 假設我有一個類, Foo ,使用靜態方法notThreadSafe ,我有兩個線程需要調用它:

// On thread 1
Foo.notThreadSafe();

// On thread 2
Foo.notThreadSafe();

因為它不是線程安全的, notThreadSafe將被聲明為synchronized

public static synchronized void notThreadSafe() { 
    /* ... */
}

這實際上是一樣的

public static void notThreadSafe() { 
    synchronized (Foo.class) {
        /* ... */
    }
}

Foo.class是加載的Foo類的Class實例。)

因此,當線程1進入同步塊時,如果線程2嘗試進入該塊(或在Foo.class同步的任何其他內容),則必須等待。

它不必是對同一方法的兩次調用; 我可以有兩個static synchronized方法( m1m2 ),其中線程1調用m1而線程2調用m2 ,並且對m2的調用必須等待調用m1才能完成,因為它們都在同步相同的實例( FooClass實例)。

這與getClass()什么關系? 因為同一個Class實例是Foo實例上的getClass返回的:

System.out.println(Foo.class == (new Foo()).getClass()); // true

“運行時類”是與對象的有效類型關聯的Class對象。 這意味着如果你這樣做:

Object o = new String();
System.out.println(o.getClass());

您將獲得class java.lang.String ,因為o的實際運行時類是String 你無法在編譯時預測這一點。

至於“由同步靜態方法鎖定”,它實際上意味着,對於在類ThisClass聲明的方法:

public static synchronized foo() {
    ...
}

......相當於:

public static foo() {
    synchronized(ThisClass.class) {
        ...
    }
}

也就是說,Class對象用作所有同步靜態方法的鎖。 更多關於同步塊和鎖定的信息

對於你的第二個問題,這意味着:

class A {}
class B extends A {
  public static synchronized void f() {}
}
...
A a = new B();
Class <? extends A> c = a.getClass();

c上調用f() (只能通過反射)將有效地使用與Bf()相同的鎖。 鎖將是類對象本身。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM