Nesnenin bir parametre türünün örneği olup olmadığını test edin


87

Bir nesnenin genel bir tür örneği olup olmadığını belirlemenin bir yolu var mı?

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

Bu açıkça işe yaramıyor. Bir alternatif var mı? Bir sınıfın somutlaştırılması için Java yansımasını kullanmak ve daha sonra genel tipte olduğundan emin olmak gibi T.

Yanıtlar:


129

Bu kontrolü yapmanın tek yolu Class, türü temsil eden nesneye sahip olmanızdır :

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

Eğer almak istemiyorsanız typebir yöntem parametresi olarak, belki de bunu başlatmak istiyorum:Class type = ((T) new Object()).getClass();
JordiVilaplana

9
@JordiVilaplana Bu doğru değil, size sınıf olarak java.lang.Object verecektir. Şuna bir
Sri Harsha Chilakapati

3
Kullanın:Class<T> type = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
Ton Snoei

22

Mark Peters örneğini genişletmek için, genellikle aşağıdaki gibi bir şey yapmak istersiniz:

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

11

Sınıf türünü Mark Peters tarafından belirtildiği gibi bir parametre olarak geçirmek istemiyorsanız, aşağıdaki kodu kullanabilirsiniz. David O'Meara'ya şeref.

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

5
O verirType safety: Unchecked cast from Type to Class<T>
Marco Sulla

5

Bunu deneyebilirsin

// 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
Bu çalışmıyor! Oyuncu kadrosu her tür için başarılıdır . Bu nedenle, "Kontrol edilmeyen yayın" derleme uyarısı verir.
Lii

3

Türü Tparametrelemek için Classtürün kullanıldığı yere kısıtlama koymak daha mantıklı olacaktır . Yazıyı geçtiğinizde, gibi bir şey kullanmak yerine Class<?>kullanmalısınız Class<? extends T>.


1
Çalışma zamanında T'nin tam türünü bilmek istiyorsanız, arayan kişinin Class <? T> genişler. Örneğin, Puce'un kodu Class <? T> genişler.
Theodore Murdock

1

Bu, yalnızca T türünde bir nesneye sahipseniz (kısmen) işe yarar. Sonra o nesnenin sınıfını alabilir, söz konusu nesneyle java.lang.Class<T>aynı olup olmadığını görebilir ve bulabilirsiniz.

Ancak bunun, genriklere sahip olmamızın tam da tersine gittiğine dikkat edin: genel bir tür kullanmak, gerçekte ne tür olduğunu umursamadığınızı söylemenin bir yoludur (belirtilebilecek üst ve alt sınırlara kadar).


Boş olmayan bir T örneğinde bir .getClass () çağrısından döndürülen Class <?> Sınıfının Class <T> olacağı garanti edilmez. Garanti edebileceğiniz en iyi şey bunun bir Sınıf olduğudur <? T> genişler.
Theodore Murdock
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.