2008-10-28 6 views
12

Nhìn qua một số mã Tôi đã xem qua đoạn mã sauKhi nào tôi nên sử dụng phân đoạn phương thức java 5 của Lớp?

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

và tôi muốn biết nếu đúc theo cách này có bất kỳ lợi thế hơn

trTuDocPackTypdBd.update((TrTuDocPackTypeDto)packDto); 

Tôi đã yêu cầu các nhà phát triển có trách nhiệm và ông nói rằng anh ấy đã sử dụng nó bởi vì nó là mới (mà không có vẻ như là một lý do đặc biệt tốt cho tôi), nhưng tôi bị hấp dẫn khi tôi muốn sử dụng phương pháp này.

+0

cũng xem http://stackoverflow.com/questions/7900410/why-would-i-use-java-lang-class-cast/7902048#7902048 – irreputable

Trả lời

20

Những phát biểu này không giống nhau. Phương thức truyền là lời gọi phương thức bình thường (invokevirtual hướng dẫn JVM) trong khi phương thức khác là cấu trúc ngôn ngữ (hướng dẫn checkcast). Trong trường hợp bạn hiển thị ở trên, bạn nên sử dụng biểu mẫu thứ hai: (TrTuDocPackTypeDto) packDto

Phương pháp cast được sử dụng trong lập trình phản chiếu với generics, khi bạn có thể hiện Lớp cho một số loại biến. Bạn có thể sử dụng nó như thế này:

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

này cung cấp cho bạn một cách an toàn để tránh sự thay thế không đúng cách đơn giản đúc một loại nguyên liệu để một kiểu generic:

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

Trình biên dịch sẽ cảnh báo bạn, Unchecked cast from List to List<Widget> , có nghĩa là trong dấu ba chấm, ai đó có thể đã thêm một Gadget vào danh sách thô, điều này cuối cùng sẽ gây ra một ClassCastException khi người gọi lặp lại trong danh sách được trả về (ví dụ) Widget trường hợp.

+0

Khi quét nhanh Tham chiếu ngôn ngữ, có vẻ như 'class.cast()' sẽ bỏ qua cảnh báo 'chuyển đổi không an toàn' mà trình biên dịch thường hiển thị. Là erickson cho biết, hãy sử dụng cấu trúc ngôn ngữ cho đến khi bạn không thể. ;-) –

+0

Bạn có thể giải thích những gì bạn NÊN làm trong trường hợp thứ hai? Tôi chỉ chạy vào cảnh báo trình biên dịch ngày hôm qua nhưng bỏ qua nó vì tôi lười biếng. Bạn đang đề xuất một cái gì đó như Danh sách .cast (thô)? –

+0

@Outlaw - để tránh trường hợp thứ hai, bạn cần phải sử dụng một cái gì đó như tôi đã cung cấp trong phương thức "tìm" ở trên. Tức là, bạn cần phải lặp qua 'Danh sách' và kiểm tra rằng mỗi phần tử thực sự là một' Widget'. Sau đó, bạn có thể bỏ qua cảnh báo mà bạn nhận được từ "(Danh sách ) thô". – erickson

-3

Cả hai tuyên bố này giống hệt nhau. Chọn bất kỳ cái nào bạn thấy dễ đọc hơn. Phương pháp thứ hai là phổ biến hơn trong kinh nghiệm của tôi, và nó là một lần mà tôi thích.

Tôi có xu hướng chỉ sử dụng phương pháp truyền khi tôi làm việc với sự phản chiếu và nó đẹp hơn trong tình huống đó. Tất cả những lần khác tôi thấy mình sử dụng cách thứ hai để đúc.

4

Trường hợp chính để thực hiện nó (IME) là khi bạn cần đưa an toàn vào một lớp/phương pháp chung. Do loại xóa, bạn không thể truyền tới T nhưng nếu bạn đã được cung cấp thông số Class<? extends T> thì bạn có thể sử dụng thông số đó để truyền và kết quả sẽ được gán cho biến loại T.

0

Tôi không thể tìm thấy ví dụ về phương pháp truyền và phương thức truyền có thể không. Tuy nhiên, nhìn vào mã, có vẻ như trong trường hợp không thể cast, phương thức cast ném một ClassCastException không kèm theo thông tin kiểu, trong khi cú pháp cast sẽ cung cấp cho bạn một số gợi ý (như trong, "không thể cast 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

Class.cast() hữu ích nếu bạn không biết bạn đang truyền lớp nào (nghĩa là, phản chiếu và vv). Nói chung, trước tiên bạn nên kiểm tra Class.isInstance (Object) để chắc chắn rằng bạn sẽ không nhận được một CCE. –

0

với hình thức đầu tiên

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

bạn có thể làm điều này:

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

với thứ e giây bạn không thể. Lớp đúc nên được mã hóa cứng.

Tại sao bạn sử dụng biến để truyền ở vị trí đầu tiên? Đó là một câu hỏi khác.:) Điều đầu tiên xuất hiện trong đầu là bạn không biết (tại thời gian biên dịch) lớp sẽ được đưa vào.