This discussion is archived
12 Replies Latest reply: Jan 17, 2013 7:05 AM by 984357 RSS

Generics question

984357 Newbie
Currently Being Moderated
Hi, I have a question regarding generics if anyone has time...? The following code prints "C". Why does it do that? B and C are not related. The Generic class
is instantiated with B as type argument, while the operation m is invoked with an instance of C.X. Thanks!
class A {
  class X { 
    void print() {} 
  }
}
 
class B extends A {
  class X extends A.X { void print() {} }  
}
 
class C extends A {
  class X extends A.X  { 
    void print() {
      System.out.println( "C" );     
    }
  }
}
 
class Generic<E extends A> {
  void m( E.X x ) {
    x.print();
  }
}
 
public class Main {
  public static void main( String[] args ) {
    Generic<B> g = new Generic<B> ();
    
    A a = new C();
    A.X x = ((C)a).new X();
    g.m( x ); // Prints "C"
  }
} 
Edited by: 981354 on Jan 15, 2013 2:33 AM
  • 1. Re: Generics question
    jtahlborn Expert
    Currently Being Moderated
    981354 wrote:
    Hi, I have a question regarding generics if anyone has time...? The following code prints "C". Why does it do that? B and C are not related. The Generic class
    is instantiated with B as type argument, while the operation m is invoked with an instance of C.X. Thanks!
    A.X x = ((C)a).new X();
    you are instantiating a specific class instance here, "C.X". the print() method of "C.X" prints "C". what did you expect to happen?
  • 2. Re: Generics question
    984357 Newbie
    Currently Being Moderated
    Hi,

    Yes, but the C class is not a subtype of the B class. So shouldn't there be a compilation error here?
  • 3. Re: Generics question
    jtahlborn Expert
    Currently Being Moderated
    981354 wrote:
    Hi,

    Yes, but the C class is not a subtype of the B class. So shouldn't there be a compilation error here?
    well, your code doesn't compile for me in java 6, so yes, i'd say there was an error here. what version of java are you using?
  • 4. Re: Generics question
    TPD-Opitz-Consulting-com Expert
    Currently Being Moderated
    981354 wrote:
    Yes, but the C class is not a subtype of the B class. So shouldn't there be a compilation error here?
    No because C.X is extending B.X and this is extending A.X.
    The relatinship of the containing classes does not matter, the inner classes have a family tree of their own.

    bye
    TPD
  • 5. Re: Generics question
    rp0428 Guru
    Currently Being Moderated
    >
    No because C.X is extending B.X and this is extending A.X.
    >
    No it isn't - it extends A.X.
  • 6. Re: Generics question
    984357 Newbie
    Currently Being Moderated
    Sorry if you had problems executing the code - it should work now!

    Any new insight on this?
  • 7. Re: Generics question
    800268 Expert
    Currently Being Moderated
    Looks like the compiler resolves E.X as A.X not your expected B.X. Makes sense as <E extends A> provides no guarantee that A.X will also be extended and that that class will be named X as well, so it really can only mean A.X.

    If you want specifics you'll have to look at the Java specification.
  • 8. Re: Generics question
    rp0428 Guru
    Currently Being Moderated
    >
    Sorry if you had problems executing the code - it should work now!
    >
    You didn't answer the question that was asked: what version of Java (javac) are you using?

    The code posted doesn't compile in 1.6
    >
    method m in class Generic<E> cannot be applied to given types
    required: B.X
    found: A.X
  • 9. Re: Generics question
    984357 Newbie
    Currently Being Moderated
    Well, I just copied the code from this website, made a new project and the code compiles fine (1.6.0_35). Strange!
  • 10. Re: Generics question
    abillconsl Explorer
    Currently Being Moderated
    I had to change
    void m(E.X x) {
    to
    void m(A.X x) {
    in order to get a clean compile.
  • 11. Re: Generics question
    800268 Expert
    Currently Being Moderated
    Ah, I used the Eclipse Juno compiler

    JDK7u7 gives (note I actually renamed B.X to B.Y here in the source, but it still wants a B.X ><):
    TestGenerics.java:34: error: method m in class Generic<E> cannot be applied to given types;
        g.m( x ); // Prints "C"
         ^
      required: B.X
      found: A.X
      reason: actual argument A.X cannot be converted to B.X by method invocation conversion
      where E is a type-variable:
        E extends A declared in class Generic
    JDK6u30 gives:
    TestGenerics.java:23: cannot select from a type variable
      void m( E.X x ) {
               ^
  • 12. Re: Generics question
    984357 Newbie
    Currently Being Moderated
    Thanks guys!

    Then it appears that there's an issue with the compiler version I'm using.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points