This discussion is archived
1 2 3 Previous Next 39 Replies Latest reply: Jul 24, 2010 10:59 AM by 794029 RSS

Generics problem

794029 Newbie
Currently Being Moderated
Hello,
I've been developing some tests for a resolution algorithm.

The goal is for our algorithm to resolve types to their full path name (and do so correctly).

For example (very simple):
if we had these classes:
package p1;
public class Foo{}
package p2;
public class Foo{}
package p2;
import p1.Foo;
public class Test1{
        Foo myFoo; // resolves to type p1.Foo, because of import -
                             // even though there is a "Foo" in the same package
}
package p2;

public class Test2{
        Foo myFoo; // resolves to type p1.Foo, because "Foo" is in the same package
}
Now, that example is all fine, and is clearly described in the JSP.
However, i have a more complicated example.. and I cannot find the specification in the JSP.

First of all, the JSP has an example ( [in section 4.4|http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#108850] ) that isn't even valid code:
package TypeVarMembers;

        class C { 
                void mCDefault() {}     
                public void mCPublic() {}       
                private void mCPrivate() {} 
                protected void mCProtected() {} 
        } 
        class CT extends C implements I {}
        interface I {   
                void mI(); } 
                <T extends C & I> void test(T t) {    
                        t.mI(); // OK
                        t.mCDefault(); // OK
                        t.mCPublic(); // OK 
                        t.mCPrivate(); // compile-time error
                        t.mCProtected(); // OK 
                } 
        }
Which isn't very helpful.... Anyhow here is my issue:
package p2;

public class Test<A> {

        A myA; // does this resolve to the Generic "A", or the class "A"?
        public class A{}
}
Nowhere can i find the specification on which resolution is correct.
When I run the Code in Eclipse, "myA" is of type p2.Test.A*.
When i run the Code in Netbeans or from the Command line, "myA" is a Generic of type <A> (within, p2.Test)

Does anyone know where in the JSP this would be clarified? or any other resources. I've got even weirder cases as well.
  • 1. Re: Generics problem
    843793 Newbie
    Currently Being Moderated
    00jt wrote:
    package p2;
    
    public class Test<A> {
    
    A myA; // does this resolve to the Generic "A", or the class "A"?
    public class A{}
    }
    Nowhere can i find the specification on which resolution is correct.
    When I run the Code in Eclipse, "myA" is of type p2.Test.A*.
    When i run the Code in Netbeans or from the Command line, "myA" is a Generic of type <A> (within, p2.Test)

    Does anyone know where in the JSP this would be clarified? or any other resources. I've got even weirder cases as well.
    If I see it right, this is because there is a class A so A myA is that class and not the class you instantiated Test with.
  • 2. Re: Generics problem
    794029 Newbie
    Currently Being Moderated
    pete_d wrote:
    00jt wrote:
    package p2;
    
    public class Test<A> {
    
    A myA; // does this resolve to the Generic "A", or the class "A"?
    public class A{}
    }
    Nowhere can i find the specification on which resolution is correct.
    When I run the Code in Eclipse, "myA" is of type p2.Test.A*.
    When i run the Code in Netbeans or from the Command line, "myA" is a Generic of type <A> (within, p2.Test)

    Does anyone know where in the JSP this would be clarified? or any other resources. I've got even weirder cases as well.
    If I see it right, this is because there is a class A so A myA is that class and not the class you instantiated Test with.
    So, Eclipse is right and Netbeans & java from the command line is wrong?
  • 3. Re: Generics problem
    843793 Newbie
    Currently Being Moderated
    00jt wrote:
    pete_d wrote:
    00jt wrote:
    package p2;
    
    public class Test<A> {
    
    A myA; // does this resolve to the Generic "A", or the class "A"?
    public class A{}
    }
    Nowhere can i find the specification on which resolution is correct.
    When I run the Code in Eclipse, "myA" is of type p2.Test.A*.
    When i run the Code in Netbeans or from the Command line, "myA" is a Generic of type <A> (within, p2.Test)

    Does anyone know where in the JSP this would be clarified? or any other resources. I've got even weirder cases as well.
    If I see it right, this is because there is a class A so A myA is that class and not the class you instantiated Test with.
    So, Eclipse is right and Netbeans & java from the command line is wrong?
    My initial reaction is yes. I've always thought if there is an actual class that class will be used over the generic placeholder. Hmm.

    Edited by: pete_d on Jul 23, 2010 4:47 PM

    Checked it with A as a separate class. same thing
  • 4. Re: Generics problem
    794029 Newbie
    Currently Being Moderated
    pete_d wrote:
    00jt wrote:
    pete_d wrote:
    00jt wrote:
    package p2;
    
    public class Test<A> {
    
    A myA; // does this resolve to the Generic "A", or the class "A"?
    public class A{}
    }
    Nowhere can i find the specification on which resolution is correct.
    When I run the Code in Eclipse, "myA" is of type p2.Test.A*.
    When i run the Code in Netbeans or from the Command line, "myA" is a Generic of type <A> (within, p2.Test)

    Does anyone know where in the JSP this would be clarified? or any other resources. I've got even weirder cases as well.
    If I see it right, this is because there is a class A so A myA is that class and not the class you instantiated Test with.
    So, Eclipse is right and Netbeans & java from the command line is wrong?
    My initial reaction is yes. I've always thought if there is an actual class that class will be used over the generic placeholder. Hmm.

    Edited by: pete_d on Jul 23, 2010 4:47 PM

    Checked it with A as a separate class. same thing
    Just to clear it up:
    public class Test<A> {
    
        A myA; // does this resolve to the Generic "A", or the class "A"?
        public static class A{}
    
        public static void main(String [] args)
        {
            Test<String> t =  new Test<String>();
            t.myA =    "hi";     //Only Works in Netbeans and Java from the command line(use of generic type)
            t.myA = new A(); //Only Works in Eclipse (use of class type "Test.A")
        }
    }
    So, Netbeans&java is wrong?
  • 5. Re: Generics problem
    843793 Newbie
    Currently Being Moderated
    00jt wrote:
    pete_d wrote:
    00jt wrote:
    pete_d wrote:
    00jt wrote:
    package p2;
    
    public class Test<A> {
    
    A myA; // does this resolve to the Generic "A", or the class "A"?
    public class A{}
    }
    Nowhere can i find the specification on which resolution is correct.
    When I run the Code in Eclipse, "myA" is of type p2.Test.A*.
    When i run the Code in Netbeans or from the Command line, "myA" is a Generic of type <A> (within, p2.Test)

    Does anyone know where in the JSP this would be clarified? or any other resources. I've got even weirder cases as well.
    If I see it right, this is because there is a class A so A myA is that class and not the class you instantiated Test with.
    So, Eclipse is right and Netbeans & java from the command line is wrong?
    My initial reaction is yes. I've always thought if there is an actual class that class will be used over the generic placeholder. Hmm.

    Edited by: pete_d on Jul 23, 2010 4:47 PM

    Checked it with A as a separate class. same thing
    Just to clear it up:
    public class Test<A> {
    
    A myA; // does this resolve to the Generic "A", or the class "A"?
    public static class A{}
    
    public static void main(String [] args)
    {
    Test<String> t =  new Test<String>();
    t.myA =    "hi";     //Only Works in Netbeans and Java from the command line(use of generic type)
    t.myA = new A(); //Only Works in Eclipse (use of class type "Test.A")
    }
    }
    So, Netbeans&java is wrong?
    Honestly I don't know though I'm more inclined to think javac has the correct interpretation I just can't see why.
  • 6. Re: Generics problem
    794029 Newbie
    Currently Being Moderated
    Here's why this is confusing:

    "the rules of [§6.5|http://java.sun.com/docs/books/jls/third_edition/html/names.html#106941] specify that a variable will be chosen in preference to a type, and that a type will be chosen in preference to a package."

    "A type variable ([§4.4|http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#108850]) is an unqualified identifier."



    So, in choice between a variable/type/package:

    Variable before Type before Package;
    But where does "*type variable*" fit into that equation.. it is BOTH.
  • 7. Re: Generics problem
    843793 Newbie
    Currently Being Moderated
    00jt wrote:
    Here's why this is confusing:

    "the rules of [§6.5|http://java.sun.com/docs/books/jls/third_edition/html/names.html#106941] specify that a variable will be chosen in preference to a type, and that a type will be chosen in preference to a package."

    "A type variable ([§4.4|http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#108850]) is an unqualified identifier."



    So, in choice between a variable/type/package:

    Variable before Type before Package;
    But where does "*type variable*" fit into that equation.. it is BOTH.
    hmm...I'm looking through the AngelikaLanger tutorial where I thought I came across this but can't find it so far.

    Edited by: pete_d on Jul 23, 2010 5:14 PM

    The rules are definitely important to know, but right now the most expedient thing I can think of is to avoid the clash in the first place.

    Edited by: pete_d on Jul 23, 2010 5:30 PM

    Yes, the only thing I can see avoiding this is to be more imaginative with class names.
  • 8. Re: Generics problem
    843793 Newbie
    Currently Being Moderated
    00jt wrote:
    When I run the Code in Eclipse, "myA" is of type p2.Test.A*.
    When i run the Code in Netbeans or from the Command line, "myA" is a Generic of type <A> (within, p2.Test)
    You need to identify what JDK each is compiling with. Chances are that they're both Sun compilers, but different versions. You can change
    the compiler in Eclpise to match that Netbeans is using to see that they do the same thing.

    Btw, a way to think about this is that the parameter <A> is hidden by local A. There should be a compiler warning for this. Do you have all warnings enabled?
  • 9. Re: Generics problem
    YoungWinston Expert
    Currently Being Moderated
    00jt wrote:
    Nowhere can i find the specification on which resolution is correct.
    When I run the Code in Eclipse, "myA" is of type p2.Test.A*.
    When i run the Code in Netbeans or from the Command line, "myA" is a Generic of type <A> (within, p2.Test)
    The Netbeans version sounds closer to me.

    The problem with generics is that you're not dealing with an established type. Type erasure means that the runtime type of myA is 'Object'; but the type validated by the compiler will be dependent on however you set up your instance of Test - and don't forget that you can always say:
    Test t = new Test();
    if you're prepared to ignore warnings; in which case the compile time validation will also be based on Object.

    Winston
  • 10. Re: Generics problem
    843793 Newbie
    Currently Being Moderated
    00jt wrote:
    The goal is for our algorithm to resolve types to their full path name (and do so correctly).
    The devil's in the details.

    May I ask why you need to do this?
  • 11. Re: Generics problem
    843793 Newbie
    Currently Being Moderated
    Yeah. Good question.

    And OP, are you using getClass().getCanonicalName() or similar?
  • 12. Re: Generics problem
    794029 Newbie
    Currently Being Moderated
    I'm back for a bit.. sorry for the delayed response.
    wastrel wrote:
    00jt wrote:
    The goal is for our algorithm to resolve types to their full path name (and do so correctly).
    The devil's in the details.

    May I ask why you need to do this?
    Yes, the details are the hard part. Getting the resolution for 90% of all cases only took a day, but the last 10% of rare corner cases is taking weeks.
    I'm part of a large group that is working on developing a processor (used for embedded systems).
    This system is a hardware implementation of the JVM.. meaning that the functionality of some of Java's bytecodes are being implemented in hardware, and thus we cannot use any of the existing JVM software, or class loaders. Its a very complicated project, and one of my small jobs is to make several test cases to see if our resolution algorithm is accurate. The programmers will be running/testing code in software, and then we transfer it over to hardware for more testing.
    We don't want our algorithm to give wrong results.. It would be bad if we expected one outcome (based testing in software), and then got a completely different result because of a resolution bug.
    We want to cover all corner cases (e.g. if someone coded the example i came up with, we would give the "RIGHT" result". )
    {quote:title=DMF. wrote:}{quote}
    Yeah. Good question.

    And OP, are you using getClass().getCanonicalName() or similar?
    Yes, thats how i'm double checking from the command line with java. But, since im developing so many tests its faster to use Netbeans or Eclipse.

    Also, in some cases I can't get the resolution at a particular spot in the code. (such as in the "extends" statement).
    Consider this example:


    {code}
    public class Example {
    public static void main(String [] args)
    {
    new Example().foo();
    }
    void foo(){
    class A{ // Example.foo().A
    int x = 10;
    }
    class B extends A{} // Netbeans thinks this extends "Example.A", but it really should be "Example.foo().A"
    System.out.println(new B().x); // Example.foo().B - prints "10" (except in Netbeans, it prints "5")
    System.out.println(new A().x); // Example.foo().A - prints "10"
    }
    class A{ // Example.A
    int x =5;
    }
    }{code}

    Even though "A" in the "extends" and "A" in the print statement are in the same context.. the resolution is different in Netbeans. And I wouldn't have found that from the command line... because i can't get the "getCanonicalName()" in the "extends" statement.

    Sufficed to say... I've found several bugs in both netbeans & Eclipse's algorithm. (usually one gets it right, and the other gets it wrong for each Bug... I've reported several bugs to Eclipse and Netbeans.. and some of them have been fixed for the next build (or as they say).

    Usually i point them to the "rule" in JLS that +proves+ that they have a bug.
    However in this example I'm not entirely sure which is "right" since the JLS doesn't seem to specify.
  • 13. Re: Generics problem
    794029 Newbie
    Currently Being Moderated
    YoungWinston wrote:
    00jt wrote:
    Nowhere can i find the specification on which resolution is correct.
    When I run the Code in Eclipse, "myA" is of type p2.Test.A*.
    When i run the Code in Netbeans or from the Command line, "myA" is a Generic of type <A> (within, p2.Test)
    The Netbeans version sounds closer to me.

    The problem with generics is that you're not dealing with an established type. Type erasure means that the runtime type of myA is 'Object'; but the type validated by the compiler will be dependent on however you set up your instance of Test - and don't forget that you can always say:
    Test t = new Test();
    if you're prepared to ignore warnings; in which case the compile time validation will also be based on Object.

    Winston
    Very true, but thats not really the problem we are trying to analyze.

    when we see:
    Test t = new Test();
    I want to know where "Test" is coming from, which is similar to finding the "type" of t but not exactly the same.
    The same applies to generics. If i see:
    class Foo<A>{
    
        class A{}
        A myA;   /// I want to know which "A" is being used here, the generic, or the class.
    }
  • 14. Re: Generics problem
    794029 Newbie
    Currently Being Moderated
    double post.. sorry.

    Edited by: 00jt on Jul 24, 2010 11:15 AM
1 2 3 Previous Next