23

Possible Duplicate:
Java: Instanceof and Generics

I am trying to write a function which cast a generic List to specific type List. Find the code below

public <T>List<T> castCollection(List srcList, Class<T> clas){
    List<T> list =new ArrayList<T>();
    for (Object obj : srcList) {
       if(obj instanceof T){
            ...
       }
    }
    return list;
}

But obj instanceof T showing a compilation error -

Cannot perform instanceof check against type parameter T. Use instead its erasure Object >instead since further generic type information will be erased at runtime.

any clarification or way to get the desired result?

Thanks in advance. :)

Community
  • 1
  • 1
Subhrajyoti Majumder
  • 40,646
  • 13
  • 77
  • 103
  • 1
    .. because you didn't search (-1); try `[java] generic instanceof` http://stackoverflow.com/questions/1570073/java-instanceof-and-generics , http://stackoverflow.com/questions/13768049/use-instanceof-in-a-generic-way , http://stackoverflow.com/questions/8741984/why-t-instanceof-t-is-not-allowed-where-t-is-a-type-parameter-and-t-is-a-varia?lq=1 , http://stackoverflow.com/questions/4397660/generics-and-instanceof-java?rq=1 (etc) –  Jan 09 '13 at 05:28

5 Answers5

41

You cannot do it this way. Fortunately, you already have a Class<T> argument so instead do

myClass.isAssignableFrom(obj.getClass())

This will return true if obj is of class myClass or subclass.

As @ILMTitan pointed out (thanks), you will need to check for obj == null to avoid a potential NullPointerException, or use myClass.isInstance(obj) instead. Either does what you need.

Lucas
  • 3,376
  • 6
  • 31
  • 46
Jim Garrison
  • 85,615
  • 20
  • 155
  • 190
  • 5
    That can cause a null pointer of obj is `null`. `isInstance()` will not cause the null pointer problem. – ILMTitan Jan 09 '13 at 05:19
  • Also note that `isAssignableFrom()` returns true even if `obj` "can be converted to" `myClass`. Prefer `isInstance()` which returns true if obj "is an instance of the represented class (or of any of its subclasses)" – Kashyap Dec 14 '18 at 18:40
11

Short answer: because a type parameter in Java is something just used by the compiler to grant type safety.

At runtime, type information about generic types is discarded because of type erasure but instanceof is a runtime check that needs a concrete type (not a type variable) to work.

Jack
  • 131,802
  • 30
  • 241
  • 343
  • 1
    Is there an `instanceof` analog for checking at compile-time? In my case, I'm trying to throw a `ClassCastException` as part of my definition of `Queue`'s `add` method. My first thought was `instanceof` but I got `error: illegal generic type for instanceof` during compilation. – Ungeheuer Sep 21 '17 at 03:47
  • @Ungeheuer You should bound your type variable. – Jack Sep 21 '17 at 13:54
4

T is a parameterized type and exists for compilation purposes. It does not exist at runtime because of type erasure.

Therefore, obj instanceof T is not legal.

fge
  • 119,121
  • 33
  • 254
  • 329
4

Because java uses erasure, generic types can not be used to check against.

To get the desired result, use Class.isInstance().

ILMTitan
  • 10,751
  • 3
  • 30
  • 46
2

Generic types will be erased after compilation (generics are for compile time type safety) and will be replaced with most applicable type after compilation.

If you want make this compile, replace T with concrete type, example

obj instance String
kosa
  • 65,990
  • 13
  • 130
  • 167