Các diễn viên là kỹ thuật có thể. Nó không thể dễ dàng được chứng minh bởi javac rằng nó không phải như vậy trong trường hợp của bạn và JLS thực sự định nghĩa đây là một chương trình Java hợp lệ, do đó việc gắn cờ lỗi sẽ không chính xác.
Điều này là do Listmột giao diện. Vì vậy, bạn có thể có một lớp con của một Datethực tế thực hiện Listngụy trang như Listở đây - và sau đó đúc nó Datesẽ hoàn toàn ổn. Ví dụ:
public class SneakyListDate extends Date implements List<Foo> {
...
}
Và sau đó:
List<Foo> list = new SneakyListDate();
Date date = (Date) list; // This one is valid, compiles and runs just fine
Việc phát hiện một kịch bản như vậy có thể không phải lúc nào cũng có thể, vì nó sẽ yêu cầu thông tin thời gian chạy nếu ví dụ đến từ, ví dụ, một phương thức thay thế. Và thậm chí nếu, nó sẽ đòi hỏi nhiều nỗ lực hơn cho trình biên dịch. Trình biên dịch chỉ ngăn chặn các phôi hoàn toàn không thể do không có cách nào để cây lớp khớp hoàn toàn. Đó không phải là trường hợp ở đây, như đã thấy.
Lưu ý rằng JLS yêu cầu mã của bạn phải là một chương trình Java hợp lệ. Trong 5.1.6.1. Chuyển đổi tham chiếu được phép thu hẹp cho biết:
Chuyển đổi tham chiếu thu hẹp tồn tại từ loại Stham chiếu sang loại tham chiếu Tnếu tất cả các điều sau đây là đúng :
- [...]
- Một trong những trường hợp sau đây được áp dụng :
- [...]
Slà một loại giao diện, Tlà một loại lớp và Tkhông đặt tên một finallớp.
Vì vậy, ngay cả khi trình biên dịch có thể nhận ra rằng trường hợp của bạn thực sự không thể chứng minh được, thì nó cũng không được phép gắn cờ vì JLS định nghĩa nó là chương trình Java hợp lệ.
Nó sẽ chỉ được phép hiển thị một cảnh báo.
Listở đây.Date d = (Date) new Object();