This discussion is archived
1 Reply Latest reply: Sep 13, 2010 2:26 AM by EJP RSS

Compiler bug? Skipped type checks?

843810 Newbie
Currently Being Moderated
Hello,

I was wondering if you could take a look at the following program. I would have expected it to fail with a ClassCastException, but it turns out to run OK. Why would I expect it to fail? Well, I'm invoking the method c.self(). Since C puts T = B, this method (inherited from A) should be attempting to cast "this" to B, which is clearly impossible since "this" is an instance of C and is unrelated to the class B (in fact no instance of B was ever created). However, everything works out fine since the caller actually doesn't use the returned object for anything. It turns out that if we replace the main() method by:

          C c = new C();
          B b = c.self();
          System.out.println("Hello.");

We actually get the expected ClassCastException - but not in A as I would have expected but in Main, due to the assignment of c.self() to b which is of type B - even though the culprit class (which generates a warning, as it should) is in A.

Is this correct and could someone point me to the place in JLS that means that it is OK to skip type checks such as this? Thanks.

public class Tester {
     static class A<T extends A>
     {
          public T self()
          {
               return (T)this;
          }          
     }
     
     static class B extends A
     {
          
     }
     
     static class C extends A<B>
     {
          
     }
     
     public static void main(String[] args)
     {
          C c = new C();
          c.self();
          System.out.println("Hello.");
     }
}
  • 1. Re: Compiler bug? Skipped type checks?
    EJP Guru
    Currently Being Moderated
    Generics are erased at compile time. Specifically, T is erased to its upper bound, which is A. The type check you refer to therefore cannot occur inside the self() method, so it occurs where the result of self() is assigned in the caller. If it isn't assigned, no error.