Results 1 to 10 of 10

Thread: Eclise bug?

  1. #1
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,004
    Blog Entries
    7
    Rep Power
    20

    Default Eclipse bug?

    Greetings,

    I read about this here (reply #21 by '00jt'. The code is simplified and replicated here:

    Java Code:
    public class T {
    
    	public static void main(String[] args) {
    	        System.out.println( "value =  " + A.B.length.length());
    	}
    }
    
    class A {
    	 
        public static class B {
            public static String length = "very long";
        }
     
        private  int [] B = new int[5];    
    }
    Of course this is pathetic code but Eclipse refuses to compile it: it says that 'B' is not visible in the main( ... ) method of class T, which obviously isn't true. When you take out the last line of class A (the private array member), the code compiles fine.

    I didn't dare to reply in the original thread (see above) because that discussion took an entirely different turn and the participants in that thread aren't compiler nerds such as I am.

    There are two members named 'B' in class A; one is a public static class and the other one is a (non static) array of ints. I read the JLS again but I couldn't find a definitive answer whether or not this code should be valid (or not), that's why I posted it here for everybody to enjoy. I suspect that the real error is in class A (two members (not methods)) with the same name; still Eclipse doesn't whine about that but it whines about the reference of such (invisible) member in class T. Javac doesn't complain about the code and it is the reference implementation by definition but I don't like those policital arguments ;-)

    Have fun with it and

    kind regards,

    Jos
    Last edited by JosAH; 06-25-2010 at 09:36 PM. Reason: stupid typo in title

  2. #2
    r035198x is offline Senior Member
    Join Date
    Aug 2009
    Posts
    2,388
    Rep Power
    7

    Default

    Looks like the namespace search starts with instance variables and stops on the first match.
    That's why they said B is not visible because the match was on the array and it is private.

  3. #3
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    11,450
    Rep Power
    18

    Default

    IntelliJ does the same. Haven't got Netbeans on this box to see if that does the same.

    It is odd that it would even look at a non-static member in this case. What I find interesting is if you make the int[] public and static, and remove the call to length(), in IntelliJ it still picks the member, and doesn't flag a conflict between the array and the class.

  4. #4
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,004
    Blog Entries
    7
    Rep Power
    20

    Default

    Quote Originally Posted by Tolls View Post
    IntelliJ does the same. Haven't got Netbeans on this box to see if that does the same.

    It is odd that it would even look at a non-static member in this case. What I find interesting is if you make the int[] public and static, and remove the call to length(), in IntelliJ it still picks the member, and doesn't flag a conflict between the array and the class.
    I read (parts of) the JLS again this morning: 6.3.2 reads:

    Quote Originally Posted by JLS
    6.3.2 Obscured Declarations
    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.
    The second 'B' in class A obscured the first 'B' (the nested class); it seems that name resolution doesn't happen according to its syntactic context in class T, i.e. 'A.B.' certainly can't reference a non static something but the algorithm described in 6.3.2 (and 6.5) dictates that expression names go before type names so the second B (although it isn't static) is picked.

    I find that strange and I find it even stranger that javac blindly follows that rule; the rule doesn't make sense here; aamof it never makes sense when it comes to static versus non-static elements ...

    kind regards,

    Jos

  5. #5
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,004
    Blog Entries
    7
    Rep Power
    20

    Default

    Quote Originally Posted by Tolls View Post
    IntelliJ does the same.
    Does IntelliJ come with its own compiler? I know that NetBeans comes with Javac (no surprise) and it compiles and runs the code without any objections ... (which I find strange, see my previous reply).

    kind regards,

    Jos

  6. #6
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    11,450
    Rep Power
    18

    Default

    No idea.
    Or should that be IDEA...ho ho.

    Obviously we build using whatever SDK is our current target, but I have no idea if there is an internal one used for tracking errors as you go.

    As you say, it's an odd one. And another reason to avoid using the same name for things in the same java file, so you avoid these quirks.

  7. #7
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,004
    Blog Entries
    7
    Rep Power
    20

    Default

    Quote Originally Posted by Tolls View Post
    As you say, it's an odd one. And another reason to avoid using the same name for things in the same java file, so you avoid these quirks.
    You're right of course; I didn't even know before today that class definitions and variable definitions in the same scope were allowed to have the same name. I didn't even know that one shadowed the other in such context.

    But, the nitpicker that I am, I want to know the hows, whys and whats, even if the code example is highly hypothetical and/or useless; it can be done according to the JLS so it should be done like that ;-) Basically all I want to know is *what* that JLS actually says in this particular (artificial) case ...

    kind regards,

    Jos

  8. #8
    Eranga's Avatar
    Eranga is offline Moderator
    Join Date
    Jul 2007
    Location
    Colombo, Sri Lanka
    Posts
    11,372
    Blog Entries
    1
    Rep Power
    19

    Default

    Quote Originally Posted by Tolls View Post
    IntelliJ does the same. Haven't got Netbeans on this box to see if that does the same.

    It is odd that it would even look at a non-static member in this case. What I find interesting is if you make the int[] public and static, and remove the call to length(), in IntelliJ it still picks the member, and doesn't flag a conflict between the array and the class.
    I've test this on NetBeans and happens the same. Original code working fine and the your suggestion too.

  9. #9
    Eranga's Avatar
    Eranga is offline Moderator
    Join Date
    Jul 2007
    Location
    Colombo, Sri Lanka
    Posts
    11,372
    Blog Entries
    1
    Rep Power
    19

    Thumbs up

    Quote Originally Posted by JosAH View Post
    I know that NetBeans comes with Javac (no surprise) and it compiles and runs the code without any objections ... (which I find strange, see my previous reply).
    Yes it's, its strange to me too. And also as I said earlier I've test what Tolls said on NetBeans and it works fine too. Once I changed int array to public static, it finds the static member, not the class B.

  10. #10
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,004
    Blog Entries
    7
    Rep Power
    20

    Default

    Quote Originally Posted by Eranga View Post
    Yes it's, its strange to me too. And also as I said earlier I've test what Tolls said on NetBeans and it works fine too. Once I changed int array to public static, it finds the static member, not the class B.
    NetBeans uses Javac and that one is not the problem, we already knew that; the bug is in Eclipse when it comes to 'obscuring' definitions (read paragraph 6.3.2 above in one of my previous replies). What surprises me is that in a context 'A.B.length' in class T only the static type B can be refered, not the non-static array B (as Eclipse did).

    I know that types are stored in a different name space (symbol table) from variables but imho 'obscuring' should never have been allowed in the language definition. 'A.B.length' can syntactically mean two things:

    1) the length variable of the nested type B
    2) the length of array B

    Obscuring picks option 2) which is (of course) invalid here but Eclipse falls into the trap: it should've picked option 1) because of the static context. Also imho there's an omission in the JLS.

    kind regards,

    Jos

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •