Example

Using generics to define the type in instanceof

Consider the following generic class Example declared with the formal parameter :

class Example {

public boolean isTypeAString(String s) {

return s instanceof T; // Compilation error, cannot use T as class type here

}

}

This will always give a Compilation error because as soon as the compiler compiles the Java source into Java bytecode it applies a process known as type erasure, which converts all generic code into non-generic code, making impossible to distinguish among T types at runtime. The type used with instanceof has to be

The following class represents what two different classes of Example, Example and Example, look like after generics has stripped off by type erasure:

class Example { // formal parameter is gone

public boolean isTypeAString(String s) {

return s instanceof Object; // Both and are now Object

}

}

Since types are gone, it's not possible for the JVM to know which type is T.

Exception to the previous rule

You can always use unbounded wildcard (?) for specifying a type in the instanceof as follows:

public boolean isAList(Object obj) {

return obj instanceof List>;

}

This can be useful to evaluate whether an instance obj is a List or not:

System.out.println(isAList("foo")); // prints false

System.out.println(isAList(new ArrayList()); // prints true

System.out.println(isAList(new ArrayList()); // prints true

In fact, unbounded wildcard is considered a reifiable type.

Using a generic instance with instanceof

The other side of the coin is that using an instance t of T with instanceof is legal, as shown in the following example:

class Example {

public boolean isTypeAString(T t) {

return t instanceof String; // No compilation error this time

}

}

because after the type erasure the class will look like the following:

class Example { // formal parameter is gone

public boolean isTypeAString(Object t) {

return t instanceof String; // No compilation error this time

}

}

Since, even if the type erasure happen anyway, now the JVM can distinguish among different types in memory, even if they use the same reference type (Object), as the following snippet shows:

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

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐