Những gì bạn đang cố gắng làm là rất hữu ích và tôi thấy rằng tôi cần phải làm điều đó rất thường xuyên trong mã mà tôi viết. Một trường hợp sử dụng ví dụ:
Giả sử chúng tôi có một giao diện Foo
và chúng tôi có một zorking
gói có ZorkingFooManager
tạo và quản lý các phiên bản của gói riêng tư ZorkingFoo implements Foo
. (Một kịch bản rất phổ biến.)
Vì vậy, ZorkingFooManager
cần phải chứa một private Collection<ZorkingFoo> zorkingFoos
nhưng nó cần phải phơi bày a public Collection<Foo> getAllFoos()
.
Hầu hết các lập trình viên java sẽ không nghĩ hai lần trước khi thực hiện getAllFoos()
như phân bổ một cái mới ArrayList<Foo>
, điền vào nó với tất cả các yếu tố từ zorkingFoos
và trả lại nó. Tôi thích giải trí với suy nghĩ rằng khoảng 30% tất cả các chu kỳ đồng hồ được sử dụng bởi mã java chạy trên hàng triệu máy trên khắp hành tinh sẽ không làm được gì ngoài việc tạo ra các bản sao ArrayLists vô dụng như vậy được thu gom rác sau vài giây.
Tất nhiên, giải pháp cho vấn đề này là xuống bộ sưu tập. Đây là cách tốt nhất để làm điều đó:
static <T,U extends T> List<T> downCastList( List<U> list )
{
return castList( list );
}
Điều này đưa chúng ta đến castList()
chức năng:
static <T,E> List<T> castList( List<E> list )
{
@SuppressWarnings( "unchecked" )
List<T> result = (List<T>)list;
return result;
}
Biến trung gian result
là cần thiết do sự sai lệch của ngôn ngữ java:
return (List<T>)list;
tạo ra một ngoại lệ "diễn viên không được kiểm tra"; càng xa càng tốt; nhưng sau đó:
@SuppressWarnings( "unchecked" ) return (List<T>)list;
là việc sử dụng bất hợp pháp các chú thích cảnh báo đàn áp.
Vì vậy, mặc dù nó không được sử dụng nhiều hơn @SuppressWarnings
trên một return
câu lệnh, nhưng rõ ràng vẫn ổn khi sử dụng nó trên một bài tập, vì vậy biến "kết quả" bổ sung sẽ giải quyết vấn đề này. (Nó nên được tối ưu hóa đi bằng trình biên dịch hoặc bằng JIT.)