I know that generic type information is stripped prior to final compilation
This is not quite true, as erasure is a part of the compilation process itself, not something that happens prior to compilation. i.e. erasure is not a transformation that happens on source code.
As such, there is no way (that I know of) to programmatically get a transformed version of the source code, but we can figure out what happens for simple examples like this by following the rules in JLS 4.6:
Type erasure is a mapping from types (possibly including parameterized
types and type variables) to types (that are never parameterized types
or type variables). We write |T| for the erasure of type T. The
erasure mapping is defined as follows:
The erasure of a parameterized type (§4.5) G<T1,...,Tn> is |G|.
The erasure of a nested type T.C is |T|.C.
The erasure of an array type T[] is |T|[].
The erasure of a type variable (§4.4) is the erasure of its leftmost bound.
The erasure of every other type is the type itself.
Type erasure also maps the signature (§8.4.2) of a constructor or method to a signature that has no parameterized types or type variables. The erasure of a constructor or method signature s is a signature consisting of the same name as s and the erasures of all the formal parameter types given in s.
The return type of a method (§8.4.5) and the type parameters of a generic method or constructor (§8.4.4, §8.8.4) also undergo erasure if the method or constructor's signature is erased.
The erasure of the signature of a generic method has no type parameters.
For your code snippet we get (ignoring trivial erasures):
Predicate<Object> -> Predicate
Predicate<? super Integer> -> Predicate
Yielding:
public static void main(String[] args) {
Predicate objPredicate = (Object c) -> c.toString().length() > 2 ;
Predicate predicate = objPredicate;
Number n = Integer.valueOf(22);
System.out.println(predicate.test(n)); //this line does not compile
}
Furthermore, the erased signature of the Predicate::test
method is:
boolean test(Object t)