Kiểm tra xem đối tượng có phải là phiên bản của một kiểu tham số không


82

Có cách nào để xác định xem một đối tượng có phải là một thể hiện của kiểu chung không?

public <T> test(Object obj) {
    if (obj instanceof T) {
        ...
    }
}

Điều đó rõ ràng không hoạt động. Có giải pháp thay thế không? Giống như tôi muốn sử dụng phản chiếu Java để khởi tạo một lớp và sau đó kiểm tra để đảm bảo rằng nó thuộc loại chung T.

Câu trả lời:


125

Cách duy nhất bạn có thể thực hiện kiểm tra này là nếu bạn có Classđối tượng đại diện cho kiểu:

Class<T> type; //maybe passed into the method
if ( type.isInstance(obj) ) {
   //...
}

Nếu bạn không muốn nhận typenhư một tham số phương pháp, có thể bạn muốn khởi tạo nó:Class type = ((T) new Object()).getClass();
JordiVilaplana

9
@JordiVilaplana Điều đó không đúng, nó sẽ cung cấp cho bạn java.lang.Object làm lớp. Hãy kiểm tra này: ideone.com/bxt9Jq
Sri Harsha Chilakapati

3
Sử dụng:Class<T> type = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
Ton Snoei

20

Để mở rộng mẫu của Mark Peters, bạn thường muốn làm điều gì đó như:

Class<T> type; //maybe passed to the method
if ( type.isInstance(obj) ) {
   T t = type.cast(obj);
   // ...
}

11

Nếu bạn không muốn chuyển Loại lớp làm tham số như Mark Peters đã đề cập, bạn có thể sử dụng mã sau. Kudos cho David O'Meara.

  Class<T> type = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass())
                  .getActualTypeArguments()[0];
  if (type.isInstance(obj)) {
      ...
  }

5
Nó choType safety: Unchecked cast from Type to Class<T>
Marco Sulla

5

Bạn có thể thử điều này,

// Cast your object to the generic type.
T data = null;
try {
    data = (T) obj;
} catch (ClassCastException cce) {
    // Log the error.
}

// Check if the cast completed successfully.
if(data != null) {
    // whatever....
}

7
Điều này không hoạt động! Dàn diễn viên thành công cho tất cả các loại. Đó là lý do tại sao nó đưa ra cảnh báo biên dịch "Unhecked cast".
Lii

3

Sẽ có ý nghĩa hơn nếu đặt giới hạn về nơi loại Tđược sử dụng để tham số cho Classloại. Khi bạn chuyển kiểu vào, thay vì sử dụng một cái gì đó như Class<?>, bạn nên sử dụng Class<? extends T>.


1
Nếu bạn muốn biết chính xác kiểu của T trong thời gian chạy, điều quan trọng là phải yêu cầu người gọi chuyển vào Lớp <T>, không phải Lớp <? kéo dài T>. Ví dụ, mã của Puce sẽ không biên dịch với Class <? kéo dài T>.
Theodore Murdock

1

Điều này sẽ chỉ hoạt động (một phần) nếu bạn có một đối tượng kiểu T. Sau đó, bạn có thể lấy lớp của đối tượng đó, xem java.lang.Class<T>và tìm xem nó có giống với đối tượng được đề cập hay không.

Nhưng lưu ý rằng điều này đi ngược lại chính lý do mà chúng ta có genrics: sử dụng một loại chung là một cách để nói rằng bạn không quan tâm loại thực sự của nó (lên đến giới hạn trên và dưới có thể được chỉ định).


Lớp <?> Được trả về từ lời gọi .getClass () trên một cá thể T không phải null không được đảm bảo là một Lớp <T>. Tốt nhất bạn có thể đảm bảo rằng đó là một Class <? kéo dài T>.
Theodore Murdock
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.