Runtime Type Information (RTTI) is a mechanism that allows Java programs to discover and use type information at runtime, rather than at compile time.
This capability is essential for features such as:
- Dynamic type checking
- Reflection
- Polymorphism
- Generic type handling (with limitations due to type erasure)
Why RTTI ?
At compile time, Java enforces type rules to prevent incorrect type usage. However, during execution, Java still needs to:
- Know what actual type an object is (for method dispatch)
- Handle cases like
instanceof, casting, and reflection
Program
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.List;
public class GenericsRTTIDemo {
// Generic method with Class<T> to retain type info
public static <T> T createInstance(Class<T> clazz) throws Exception {
return clazz.getDeclaredConstructor().newInstance();
}
// Generic method to check and process a list
public static void processList(List<?> list) {
System.out.println("List class: " + list.getClass().getSimpleName());
// Cannot check List<String> at runtime, but can check List
if (list instanceof List) {
System.out.println("Contains: " + list);
}
}
// Class to capture generic type at runtime
static abstract class TypeReference<T> {
Type getType() {
return ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
}
public static void main(String[] args) throws Exception {
// Demonstrate type erasure
List<String> stringList = new ArrayList<>();
List<Integer> intList = new ArrayList<>();
System.out.println("Same class at runtime? " + (stringList.getClass() == intList.getClass())); // true
// Use Class<T> to create instance
String s = createInstance(String.class);
System.out.println("Created: " + s.getClass().getSimpleName()); // String
// Process a generic list
stringList.add("Hello");
processList(stringList); // List class: ArrayList, Contains: [Hello]
// Capture generic type at runtime
TypeReference<List<String>> ref = new TypeReference<>() {};
System.out.println("Captured type: " + ref.getType()); // java.util.List<java.lang.String>
}
}
/*
Same class at runtime? true
Created: String
List class: ArrayList
Contains: [Hello]
Captured type: java.util.List<java.lang.String>
*/