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 List
một giao diện. Vì vậy, bạn có thể có một lớp con của một Date
thực tế thực hiện List
ngụy trang như List
ở đây - và sau đó đúc nó Date
sẽ 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 S
tham chiếu sang loại tham chiếu T
nế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 :
- [...]
S
là một loại giao diện, T
là một loại lớp và T
không đặt tên một final
lớ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();