Looking through some code I came across the following code

瀏覽一些代碼,我遇到了以下代碼

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

and I'd like to know if casting this way has any advantages over

而且我想知道這種方式是否有任何優勢

trTuDocPackTypdBd.update((TrTuDocPackTypeDto)packDto);

I've asked the developer responsible and he said he used it because it was new (which doesn't seem like a particularly good reason to me), but I'm intrigued when I would want to use the method.

我已經問開發人員負責了,他說他使用它是因為它是新的(這對我來說似乎不是特別好的理由),但是當我想要使用這種方法時我很感興趣。

5 个解决方案

#1

20

These statements are not identical. The cast method is a normal method invocation (invokevirtual JVM instruction) while the other is a language construct (checkcast instruction). In the case you show above, you should use the second form: (TrTuDocPackTypeDto) packDto

這些陳述並不相同。 cast方法是普通的方法調用(invokevirtual JVM指令),而另一種是語言構造(checkcast指令)。在上面顯示的情況下,您應該使用第二種形式:(TrTuDocPackTypeDto)packDto

The cast method is used in reflective programming with generics, when you have a Class instance for some variable type. You could use it like this:

當你有一個類變量類型的Class實例時,cast方法用於泛型的反射編程。你可以像這樣使用它:

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

This gives you a safe way to avoid the incorrect alternative of simply casting a raw type to a generic type:

這為您提供了一種安全的方法來避免將原始類型簡單地轉換為泛型類型的錯誤替代方法:

/* DO NOT DO THIS! */

List raw = new ArrayList();

...

return (List) raw;

The compiler will warn you, Unchecked cast from List to List, meaning that in the ellipsis, someone could have added a Gadget to the raw list, which will eventually cause a ClassCastException when the caller iterates over the returned list of (supposed) Widget instances.

編譯器會警告你,Unchecked從List轉換為List

,這意味着在省略號中,有人可能在原始列表中添加了一個Gadget,當調用者遍歷返回的列表(假設)時,最終會導致ClassCastException )小部件實例。

#2

4

The main case for doing it (IME) is when you need to safely cast in a generic class/method. Due to type erasure, you can't cast to T but if you've been provided a Class extends T> parameter then you can use that to cast and the result will be assignable to a variable of type T.

這樣做的主要情況(IME)是您需要安全地轉換為泛型類/方法。由於類型擦除,你不能轉換為T但是如果你已經提供了一個Class

參數然后你可以使用它來轉換,結果將可以賦值給類型為T的變量。

#3

0

I can't find an example where the cast method is possible and the cast syntax not. However, looking at the code, it seems that in case the cast is not possible, the cast method throws a ClassCastException with no type information attached, whereas the cast syntax will give you some hints (as in, "could not cast Snoopy to TyrannosorusRex") :

我找不到一個示例,其中cast方法是可能的,而鑄造語法不是。但是,查看代碼時,似乎在無法進行強制轉換的情況下,cast方法拋出一個沒有附加類型信息的ClassCastException,而強制轉換語法會給你一些提示(如“,”無法將Snoopy強制轉換為TyrannosorusRex “):

/**
* Casts an object to the class or interface represented
* by this Class
*
* @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;
}

#4

0

With the first form

用第一種形式

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

you can do this:

你可以這樣做:

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

With the second you can't. The casting class should be hard coded.

隨着第二個你不能。鑄造類應該是硬編碼的。

Why would you use a variable to cast in first place? That's another question. :) The first thing that comes to mind is, you don't know ( at compile time ) the class that will be casted to.

你為什么要在第一時間使用變量?那是另一個問題。 :)首先想到的是,你不知道(在編譯時)將被轉換為的類。

#5

-3

Both of these statements are identical. Pick whichever one you find more readable. The second method is more common in my experience, and it is the once that I prefer.

這兩個陳述都是相同的。選擇你認為更具可讀性的那個。第二種方法在我的經驗中更常見,它是我喜歡的一次。

I tend to use the cast method solely when I am working with reflection, and it reads nicer in that situation. All other times I find myself using the second way of casting.

我傾向於僅在使用反射時使用強制轉換方法,並且在這種情況下它看起來更好。所有其他時間我發現自己使用第二種鑄造方式。