For some time I thought I have understanding of how type erasure and generic types worked but today I stumbled upon case when generic type is used in class and unexpected type erasures happen even on types not related to generic. Consider following example class:
import java.util.Optional;
class TheClass<T> {
Optional<Something> getSomething() {
return Optional.of(new Something());
}
class Something {
int getId() {
return 1;
}
}
}
Notably it has generic that is not used at all. Class usage is following:
public class Main {
private static TheClass clazz = new TheClass<>();
public static void main(String[] args) {
clazz.getSomething().ifPresent(s -> System.out.println(((TheClass.Something) s).getId()));
}
}
clazz.getSomething().ifPresent produces warning (unchecked call to ifPresent) and inside call to if present cast is needed. If generic T is removed from abstract class then code works as expected without warning and cast.
What is the reason of observed behavior? Why javac seemingly earses all types from TheClass? Is there any workaround to avoid casting arguments and supressing uchecked warning?