title: Extensive type erasures in generic classes
body: <p>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:</p>
  
  <pre><code>import java.util.Optional;
  
  class TheClass&lt;T&gt; {
      Optional&lt;Something&gt; getSomething() {
          return Optional.of(new Something());
      }
  
      class Something {
          int getId() {
              return 1;
          }
      }
  }
  </code></pre>
  
  <p>Notably it has generic that is not used at all.  Class usage is following:</p>
  
  <pre><code>public class Main {
      private static TheClass clazz = new TheClass&lt;&gt;();
  
      public static void main(String[] args) {
          clazz.getSomething().ifPresent(s -&gt; System.out.println(((TheClass.Something) s).getId()));
      }
  }
  </code></pre>
  
  <p>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.</p>
  
  <p>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?</p>