2008-10-28 40 views
12

通過一些代碼,我碰到下面的代碼什麼時候應該使用Class 5的java 5方法強制轉換?

trTuDocPackTypdBd.update(TrTuDocPackTypeDto.class.cast(packDto)); 

,我想知道,如果鑄造這種方式在

trTuDocPackTypdBd.update((TrTuDocPackTypeDto)packDto); 

有什麼優點,我問開發商負責,他跑來找說他用它是因爲它是新的(這對我來說似乎不是一個特別好的理由),但是當我想要使用該方法時,我很感興趣。

+0

另請參閱http://stackoverflow.com/questions/7900410/why-would-i-use-java-lang-class-cast/7902048#7902048 – irreputable 2011-10-26 11:52:34

回答

20

這些敘述不完全相同。該轉換方法是一種常規方法調用(invokevirtual JVM指令),而另一種是語言結構(checkcast指令)。在上面顯示的情況下,應該使用第二種形式:(TrTuDocPackTypeDto) packDto

cast方法用於具有泛型的反射編程,當您對某些變量類型具有Class實例時。你可以使用這樣的:

public <T> Set<T> find(Class<T> clz, Filter criteria) { 
    List<?> raw = session.find(clz, criteria); /* A legacy, un-generic API. */ 
    Set<T> safe = new HashSet<T>(); 
    for (Object o : raw) 
    safe.add(clz.cast(o)); 
    return safe; 
} 

這給你一個安全的方式,以避免簡單地鑄造原始類型到一個通用的類型不正確的選擇:

/* DO NOT DO THIS! */ 
List raw = new ArrayList(); 
... 
return (List<Widget>) raw; 

編譯器會警告你,Unchecked cast from List to List<Widget> ,這意味着在省略號中,某人可能會在原始列表中添加Gadget,當調用方迭代(應該)Widget實例的返回列表時,最終會導致ClassCastException

+0

在快速掃描語言參考時,看起來`class.cast()`會繞過編譯器通常會顯示的'unsafe conversion`警告。 由於 erickson 說,使用語言結構,直到你不能。 ;-) – 2008-10-28 16:17:58

+0

你能解釋一下你應該在第二種情況下做什麼?我昨天碰到了這個編譯器警告,但由於我很懶,所以不予理睬。你是否建議像列表 .cast(原始)? – 2009-03-13 17:02:35

-3

這兩個語句都是相同的。選擇哪一個你發現更可讀。第二種方法在我的經驗中更爲常見,而且我更喜歡這種方式。

我傾向於僅在使用反射時使用投射方法,並且在那種情況下它讀取更好。所有其他時間,我發現自己使用第二種投射方式。

4

執行此操作的主要情況(IME)是當您需要安全地轉換爲通用類/方法時。由於類型擦除,你不能投射到T,但是如果你已經提供了Class<? extends T>參數,那麼你可以使用它來投射,結果將被分配給T類型的變量。

0

我找不到一個可以使用轉換方法而不使用轉換語法的例子。 然而,在代碼中,看起來如果轉換不可行,cast方法拋出一個沒有附加類型信息的ClassCastException,而轉換語法會給你一些提示(例如「無法將Snoopy投射到TyrannosorusRex「) :

/** 
* Casts an object to the class or interface represented 
* by this <tt>Class</tt> object. 
* 
* @param obj the object to be cast 
* @return the object after casting, or null if obj is null 
* 
* @throws ClassCastException if the object is not 
* null and is not assignable to the type T. 
* 
* @since 1.5 
*/ 
public T cast(Object obj) { 
if (obj != null && !isInstance(obj)) 
    throw new ClassCastException(); 
return (T) obj; 
} 
0

隨着第一種形式

trTuDocPackTypdBd.update(TrTuDocPackTypeDto.class.cast(packDto)); 

,你可以這樣做:

public void dynamicCast(Class clazz, Object o) { 
    this.x = clazz.cast(o); 
} 

在TH技術é秒你不能。鑄造類應該是硬編碼的。

爲什麼你會首先使用一個變量來投射?這是另一個問題。:)首先想到的是,你不知道(在編譯時)將被鑄造到的類。

相關問題