Generics are a compile time feature. Generics add checks at compile time which may not have any meaning at runtime. This is one example. You can only check the type of the object referenced which could be a super type in code. If you want to pass the type T you have do this explicitly.

void someMethod(Class<T> tClass) {
    if(String.class.isAssignableFrom(tClass)) 

or

void someMethod(Class<T> tClass, T tArg) {

Note: the type might not be the same,

someMethod(Number.class, 1);
Answer from Peter Lawrey on Stack Overflow
Top answer
1 of 9
95

The error message says it all. At runtime, the type is gone, there is no way to check for it.

You could catch it by making a factory for your object like this:

public static <T> MyObject<T> createMyObject(Class<T> type) {
    return new MyObject<T>(type);
}

And then in the object's constructor store that type, so variable so that your method could look like this:

if (arg0 != null && !(this.type.isAssignableFrom(arg0.getClass())) {
    return -1;
}
2 of 9
52

Two options for runtime type checking with generics:

Option 1 - Corrupt your constructor

Let's assume you are overriding indexOf(...), and you want to check the type just for performance, to save yourself iterating the entire collection.

Make a filthy constructor like this:

public MyCollection<T>(Class<T> t) {

    this.t = t;
}

Then you can use isAssignableFrom to check the type.

public int indexOf(Object o) {

    if (
        o != null &&

        !t.isAssignableFrom(o.getClass())

    ) return -1;

//...

Each time you instantiate your object you would have to repeat yourself:

new MyCollection<Apples>(Apples.class);

You might decide it isn't worth it. In the implementation of ArrayList.indexOf(...), they do not check that the type matches.

Option 2 - Let it fail

If you need to use an abstract method that requires your unknown type, then all you really want is for the compiler to stop crying about instanceof. If you have a method like this:

protected abstract void abstractMethod(T element);

You can use it like this:

public int indexOf(Object o) {

    try {

        abstractMethod((T) o);

    } catch (ClassCastException e) {

//...

You are casting the object to T (your generic type), just to fool the compiler. Your cast does nothing at runtime, but you will still get a ClassCastException when you try to pass the wrong type of object into your abstract method.

NOTE 1: If you are doing additional unchecked casts in your abstract method, your ClassCastExceptions will get caught here. That could be good or bad, so think it through.

NOTE 2: You get a free null check when you use instanceof. Since you can't use it, you may need to check for null with your bare hands.

Discussions

java - why instanceof does not work with Generic? - Stack Overflow
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 List castCollec... More on stackoverflow.com
🌐 stackoverflow.com
java - Interface generics and instanceof - Stack Overflow
My interface has a generic type argument. Any class which would implement the interface has to declare this type, so later users of it will know what they get back. Now, I need to do checks with More on stackoverflow.com
🌐 stackoverflow.com
May 26, 2013
java - How to get concrete type of a generic interface - Stack Overflow
You can grab generic interfaces of a class by Class#getGenericInterfaces() which you then in turn check if it's a ParameterizedType and then grab the actual type arguments accordingly. Type[] genericInterfaces = BarFoo.class.getGenericInterfaces(); for (Type genericInterface : genericInterfaces) { if (genericInterface instanceof ... More on stackoverflow.com
🌐 stackoverflow.com
How to check if a generic type implements a specific type of generic interface in java? - Stack Overflow
Possible Duplicate: Generic type of local variable at runtime I'm new to Java generics, and coming from a .NET world, I'm used to being able to write a method like this: public void genericMet... More on stackoverflow.com
🌐 stackoverflow.com
🌐
Baeldung
baeldung.com › home › java › core java › java instanceof operator
Java instanceof Operator | Baeldung
May 11, 2024 - We’ll also create a class Circle, which implements the Shape interface and also extends the Round class: public class Circle extends Round implements Shape { // implementation details } The instanceof result will be true if the object is an instance of the type:
🌐
Tutorjoes
tutorjoes.in › java_programming_materials › generics_to_auto_cast_and_use_of_instanceof_with_generics
Generics to auto-cast and Use of instanceof with Generics
Object obj1 = new String("foo"); // reference type Object, object type String Object obj2 = new Integer(11); // reference type Object, object type Integer System.out.println(obj1 instanceof String); // true System.out.println(obj2 instanceof String); // false, it's an Integer, not a String · Suppose the following generic interface has been declared
🌐
Rip Tutorial
riptutorial.com › use of instanceof with generics
Java Language Tutorial => Use of instanceof with Generics
The type used with instanceof has to be reifiable, which means that all information about the type has to be available at runtime, and this is usually not the case for generic types.
🌐
Tabnine
tabnine.com › home page › code › java › java.lang.class
java.lang.Class.getGenericInterfaces java code examples | Tabnine
public static Class<?> ... instanceof TypeVariable) { return genericClass.getClass(); } return (Class<?>) genericClass; } } catch (Throwable e) { } if (cls.getSuperclass() != null) { return getGenericClass(cls.getSuperclass(), i); } else { throw new IllegalArgumentException(cls.getName() + " generic type undefined!"); } } ... for (int i = 0, length = interfaces.length; i ...
Find elsewhere
🌐
Coderanch
coderanch.com › t › 375011 › java › instanceof-generics
how to use instanceof in generics (Java in General forum at Coderanch)
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums · this forum made possible by our volunteer staff, including ... ... i realize there're some limitations in generics (J2SE 1.5); one of them is "naked" type parameter can't be used in instanceof operations.
🌐
CodingTechRoom
codingtechroom.com › question › -java-instanceof-generic-types-
How to Use instanceof with Generic Types in Java - CodingTechRoom
The instanceof operator can check if an object is an instance of a raw type, but it cannot directly determine if a generic type instance (like List<String>) matches the type (List<Integer>). Use the instanceof operator with raw types. For example, to check if a List is an instance of a List, ...
🌐
DataCamp
datacamp.com › doc › java › instanceof
instanceof Keyword in Java: Usage & Examples
The instanceof keyword in Java is a binary operator used to test whether an object is an instance of a specific class or implements a particular interface.
Top answer
1 of 2
32

Java implements erasure, so there's no way to tell on runtime if genericObject is an instance of Set<String> or not. The only way to guarantee this is to use bounds on your generics, or check all elements in the set.

Compile-time Generic Bounds

Using bounds checking, which will be checked at compile-time:

public <T extends SomeInterface> void genericMethod(Set<? extends T> tSet) {
    // Do something with tSet here
}

Java 8

We can use streams in Java 8 to do this natively in a single line:

public <T> void genericMethod(T t) {
    if (t instanceof Set<?>) {
        Set<?> set = (Set<?>) t;
        if (set.stream().allMatch(String.class:isInstance)) {
            Set<String> strs = (Set<String>) set;
            // Do something with strs here
        }
    }
}

Java 7 and older

With Java 7 and older, we need to use iteration and type checking:

public <T> void genericMethod(T t) {
    Set<String> strs = new HashSet<String>();
    Set<?> tAsSet;
    if (t instanceof Set<?>) {
        tAsSet = (Set<?>) t;
        for (Object obj : tAsSet) {
            if (obj instanceof String) {
                strs.add((String) obj);
            }
        }
        // Do something with strs here
    } else {
        // Throw an exception or log a warning or something.
    }
}

Guava

As per Mark Peters' comment below, Guava also has methods that do this for you if you can add it to your project:

public <T> void genericMethod(T t) {
    if (t instanceof Set<?>) {
        Set<?> set = (Set<?>) t;
        if (Iterables.all(set, Predicates.instanceOf(String.class))) {
            Set<String> strs = (Set<String>) set;
            // Do something with strs here
        }
    }
}

The statement, Iterables.all(set, Predicates.instanceOf(String.class)) is essentially the same thing as set instanceof Set<String>.

2 of 2
13

You don't have that option in Java, sadly. In Java, there is no runtime difference between a List<String> and a List<Integer>. It is the compiler that ensures that you never add() an Integer to a List<String>. Even that compiler enforcement is not strict, so you can "legally" do such abominations with unchecked casts....

All in all, for (almost) any matter of runtime-type-identification, you have to take List<String> for what it actually is: just a raw List. That is called type erasure.

That said, nothing prevents you from inspecting the contents of a List for their types:

public boolean isListOf(List<?> list, Class<?> c) {
    for (Object o : list) {
        if (!c.isInstance(o)) return false;
    }

    return true;
}

To use this method:

    // ...
    if (genericObject instanceof List<?>) {
        if (isListOf((List<?>) genericObject, String.class)) {
            @SuppressWarnings("unchecked")
            List<String> strings = (List<String>) genericObject;
        }
    }

An interesting observation: if the list is empty, the method returns true for all given types. Actually there is no runtime difference between an empty List<String> and an empty List<Integer> whatsoever.

🌐
Coderanch
coderanch.com › t › 499793 › java-programmer-OCPJP › certification › Generics-instanceof-Operator
Generics and instanceof Operator (OCPJP forum at Coderanch)
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums · this forum made possible by our volunteer staff, including ... ... Assertion :- ref instanceOf InterfaceType results to:- true iff class of object ref directly or indirectly implements InterfaceType false otherwise.
🌐
Codemia
codemia.io › knowledge-hub › path › java_instanceof_and_generics
Java Instanceof and Generics
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises
🌐
Oracle
docs.oracle.com › javase › tutorial › java › generics › restrictions.html
Restrictions on Generics (The Java™ Tutorials > Learning the Java Language > Generics (Updated))
To use Java generics effectively, you must consider the following restrictions: Cannot Instantiate Generic Types with Primitive Types · Cannot Create Instances of Type Parameters · Cannot Declare Static Fields Whose Types are Type Parameters · Cannot Use Casts or instanceof With Parameterized Types ·
🌐
ArcGIS
desktop.arcgis.com › en › arcobjects › latest › java › 7c061b6b-7317-4d53-aa15-a9c0a43f278b.htm
Casting and runtime type checking (using instanceof)—ArcObjects 10.4 Help for Java | ArcGIS for Desktop
This style of programming has the advantage that the same method can work with many different underlying objects that implement the required interface. Thus, client code is implementation agnostic. In the Java programming language, the casting and coercing operation is used to convert between types and the instanceof operator is used to check for type information at run time.