Hai tùy chọn để kiểm tra loại thời gian chạy với generic:
Tùy chọn 1 - Tham nhũng hàm tạo của bạn
Giả sử bạn đang ghi đè indexOf (...) và bạn muốn kiểm tra loại chỉ cho hiệu suất, để tự lưu lại toàn bộ bộ sưu tập.
Tạo một nhà xây dựng bẩn thỉu như thế này:
public MyCollection<T>(Class<T> t) {
this.t = t;
}
Sau đó, bạn có thể sử dụng isAssignableFrom để kiểm tra loại.
public int indexOf(Object o) {
if (
o != null &&
!t.isAssignableFrom(o.getClass())
) return -1;
//...
Mỗi lần bạn khởi tạo đối tượng của mình, bạn sẽ phải lặp lại chính mình:
new MyCollection<Apples>(Apples.class);
Bạn có thể quyết định nó không xứng đáng. Trong quá trình triển khai ArrayList.indexOf (...) , họ không kiểm tra xem loại đó có khớp không.
Tùy chọn 2 - Hãy để nó thất bại
Nếu bạn cần sử dụng một phương thức trừu tượng yêu cầu loại không xác định của bạn, thì tất cả những gì bạn thực sự muốn là trình biên dịch ngừng khóc về instanceof . Nếu bạn có một phương pháp như thế này:
protected abstract void abstractMethod(T element);
Bạn có thể sử dụng nó như thế này:
public int indexOf(Object o) {
try {
abstractMethod((T) o);
} catch (ClassCastException e) {
//...
Bạn đang truyền đối tượng cho T (loại chung của bạn), chỉ để đánh lừa trình biên dịch. Diễn viên của bạn không làm gì khi chạy , nhưng bạn vẫn sẽ nhận được ClassCastException khi bạn cố chuyển sai loại đối tượng vào phương thức trừu tượng của mình.
LƯU Ý 1: Nếu bạn đang thực hiện các phôi không được kiểm tra bổ sung trong phương thức trừu tượng của mình, ClassCastExceptions của bạn sẽ bị bắt ở đây. Điều đó có thể là tốt hoặc xấu, vì vậy hãy suy nghĩ kỹ.
LƯU Ý 2: Bạn nhận được kiểm tra null miễn phí khi bạn sử dụng instanceof . Vì bạn không thể sử dụng nó, bạn có thể cần kiểm tra null bằng tay không.
Class.isAssignableFrom
.