This discussion is archived
1 2 3 Previous Next 39 Replies Latest reply: Jul 24, 2010 10:59 AM by 794029 Go to original post RSS
  • 15. Re: Generics problem
    YoungWinston Expert
    Currently Being Moderated
    00jt wrote:
    ...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.
    }
    My apologies, I didn't read your post properly (missed the class declaration).

    In my test (Eclipse), the class "masks" the generic. I also tried:
    import anotherpackage.A;
    class Foo<A>{
       A myA;
    }
    and it handles that completely the opposite (the generic masks the imported type).

    Seems to me that the code is a great example of why you shouldn't use single characters for class names; and conversely why you should always using them for generic type definitions.

    Winston
  • 16. Re: Generics problem
    EJP Guru
    Currently Being Moderated
    I would say Eclipse is correct here. A new scope starts at fhe { after the class declaration, so the inner A overrides the type argument A. The situation is analogous to the case or a local variable overriding a method argument with the same name.

    On the other hand you may have to deal with source code like that which relies on the Sun compiler's interpretation ;-(
  • 17. Re: Generics problem
    YoungWinston Expert
    Currently Being Moderated
    ejp wrote:
    I would say Eclipse is correct here. A new scope starts at fhe { after the class declaration, so the inner A overrides the type argument A. The situation is analogous to the case or a local variable overriding a method argument with the same name.
    Yeah, that's what I figured too.
    On the other hand you may have to deal with source code like that which relies on the Sun compiler's interpretation ;-(
    I guess it goes back to the basic question...why do this?

    Winston
  • 18. Re: Generics problem
    794029 Newbie
    Currently Being Moderated
    YoungWinston wrote:
    ejp wrote:
    I would say Eclipse is correct here. A new scope starts at fhe { after the class declaration, so the inner A overrides the type argument A. The situation is analogous to the case or a local variable overriding a method argument with the same name.
    Yeah, that's what I figured too.
    Yea, I would think that makes sense too.. but i want to have some sort of documentation (like the JLS) which would clarify this. But it all depends if "A" is a variable or a type

    Consider this code:
     
    public class Example1 {
    
        int [] A = new int[10]; // the field "A"
    
        void myMethod(){
            class A{int length = 5;} // declaration of class inside the scope "myMethod()"
            System.out.println(A.length); // this "A" is the field due to obscuring.
        }
    
        public static void main(String [] args)
        {
            new Example1().myMethod(); // prints 10
        }
    }
    Even though the class "A" is INSIDE the scope of "myMethod" and the field "A"(of type int[]) is OUTSIDE the scope of "myMethod", the field is used. This is following the rules of obscuring. Which is different from shadowing.
    public class Example2 {
    
        int [] A = new int[10]; // the field "A"
    
        void myMethod(){
             int [] A = new int[5]; // declaration of field inside the scope "myMethod()"
            System.out.println(A.length); // this "A" is the local field due to shadowing
        }
    
        public static void main(String [] args)
        {
            new Example2().myMethod(); // prints 5 due do the rules of shadowing.
        }
    }
    So this is where i want to know what a "generic type" is actually. Is it a class? ...yes, in a way. Is it a type?.. yes, in a way.

    So how does the shadowing/obscuring rules apply according to the JLS? Answer: it doesn't specify.(as far as i can tell)


    On the other hand you may have to deal with source code like that which relies on the Sun compiler's interpretation ;-(
    I guess it goes back to the basic question...why do this?

    Winston
    I agree no one should write code like that. But just because it "shouldn't ever happen" doesn't mean that we shouldn't handle it in our resolution algorithm.
    We want our algorithm to be completely correct, that is: if someone coded badly (naming a variable the same as a generic) it would still run the same on our system as it does on Java.
    We can't just say "oh well.. THAT will never happen... lets not worry about that".
  • 19. Re: Generics problem
    794029 Newbie
    Currently Being Moderated
    anyone else have ideas?
  • 20. Re: Generics problem
    EJP Guru
    Currently Being Moderated
    In this case you have a big problem as you have two conflicting implementations to emulate. I think you're just going to have to implement both and provide a switch.
  • 21. Re: Generics problem
    794029 Newbie
    Currently Being Moderated
    ejp wrote:
    In this case you have a big problem as you have two conflicting implementations to emulate. I think you're just going to have to implement both and provide a switch.
    I think the JLS needs to define this.
  • 22. Re: Generics problem
    EJP Guru
    Currently Being Moderated
    I agree completely, but you're still going to need two implementations. Either the JDK compiler has been wrong for nearly six years or Eclipse has been wrong for a similar period. So if you're going after 100% coverge you have to assume you will encounter code written for both interpretations.
  • 23. Re: Generics problem
    YoungWinston Expert
    Currently Being Moderated
    00jt wrote:
    Even though the class "A" is INSIDE the scope of "myMethod" and the field "A"(of type int[]) is OUTSIDE the scope of "myMethod", the field is used. This is following the rules of obscuring. Which is different from shadowing.
    I'm not sure about that. There are several situations (eg, method overloading) where the compiler has to make a "best choice" about how to interpret code, and in the case of your 'Example1' it's unambiguous:
    The only possible interpretation of 'A.length' that is valid is exactly the one chosen. Now if your class definition had made 'length' public and static, that's a different kettle of fish...

    Winston
  • 24. Re: Generics problem
    EJP Guru
    Currently Being Moderated
    In that case I would have expected a compile error about referring to a non-static member in a static context. I wouldn't expect the compiler to search past an incorrect possibility to find a correct possibility.
  • 25. Re: Generics problem
    YoungWinston Expert
    Currently Being Moderated
    ejp wrote:
    In that case I would have expected a compile error about referring to a non-static member in a static context. I wouldn't expect the compiler to search past an incorrect possibility to find a correct possibility.
    Duh, you're right. :-) And in all other (valid) cases I tried, it seems to pick the variable over the class.

    Winston
  • 26. Re: Generics problem
    794029 Newbie
    Currently Being Moderated
    YoungWinston wrote:
    ejp wrote:
    In that case I would have expected a compile error about referring to a non-static member in a static context. I wouldn't expect the compiler to search past an incorrect possibility to find a correct possibility.
    Duh, you're right. :-) And in all other (valid) cases I tried, it seems to pick the variable over the class.

    Winston
    This is correct since it is following the rules of obscuring: (see the JLS )
    A simple name may occur in contexts where it may potentially be interpreted as the name of a variable, a type or a package. In these situations, the rules of §6.5 specify that a variable will be chosen in preference to a type, and that a type will be chosen in preference to a package. Thus, it is may sometimes be impossible to refer to a visible type or package declaration via its simple name. We say that such a declaration is obscured.
    Obscuring is distinct from shadowing (§6.3.1) and hiding (§8.3, §8.4.8.2, §8.5, §9.3, §9.5). The naming conventions of §6.8 help reduce obscuring.
    This is where I want to know if a generic is treated like a "variable" or a "type". All i can find in the JLS is that a generic is considered a "type variable".

    I did find the "scope" definition of the generic in section 6.3:
    The scope of a constructor's type parameter is the entire declaration of the constructor, including the type parameter section itself. Therefore, type parameters can appear as parts of their own bounds, or as bounds of other type parameters declared in the same section.
    but the rules of shadowing, obscuring, and hiding are not defined for generics.
  • 27. Re: Generics problem
    843793 Newbie
    Currently Being Moderated
    00jt wrote:
    I agree no one should write code like that. But just because it "shouldn't ever happen" doesn't mean that we shouldn't handle it in our resolution algorithm.
    We want our algorithm to be completely correct, that is: if someone coded badly (naming a variable the same as a generic) it would still run the same on our system as it does on Java.
    We can't just say "oh well.. THAT will never happen... lets not worry about that".
    When any specification is silent or ambiguous you have no choice but to make a best effort. It appears that Eclipse and Netbeans have made theirs. I guess you would have to go with your own. I'm inclined to go with the "reference implementation" so at least there is that to lean on.
  • 28. Re: Generics problem
    794029 Newbie
    Currently Being Moderated
    pete_d wrote:
    00jt wrote:
    I agree no one should write code like that. But just because it "shouldn't ever happen" doesn't mean that we shouldn't handle it in our resolution algorithm.
    We want our algorithm to be completely correct, that is: if someone coded badly (naming a variable the same as a generic) it would still run the same on our system as it does on Java.
    We can't just say "oh well.. THAT will never happen... lets not worry about that".
    When any specification is silent or ambiguous you have no choice but to make a best effort. It appears that Eclipse and Netbeans have made theirs. I guess you would have to go with your own. I'm inclined to go with the "reference implementation" so at least there is that to lean on.
    My question was if anyone knows if this is specified anywhere.
    Perhaps i will just stick with what Javac seems to do.
  • 29. Re: Generics problem
    843793 Newbie
    Currently Being Moderated
    00jt wrote:
    pete_d wrote:
    00jt wrote:
    I agree no one should write code like that. But just because it "shouldn't ever happen" doesn't mean that we shouldn't handle it in our resolution algorithm.
    We want our algorithm to be completely correct, that is: if someone coded badly (naming a variable the same as a generic) it would still run the same on our system as it does on Java.
    We can't just say "oh well.. THAT will never happen... lets not worry about that".
    When any specification is silent or ambiguous you have no choice but to make a best effort. It appears that Eclipse and Netbeans have made theirs. I guess you would have to go with your own. I'm inclined to go with the "reference implementation" so at least there is that to lean on.
    My question was if anyone knows if this is specified anywhere.
    To me, the definitive sources are the "reference implementation" and then the JLS in that order. That's just me.
    Perhaps i will just stick with what Javac seems to do.
    Isn't there suppose to be some kind of official test suite to show that an implementation is "Java".