Bug 111417 - [1.5][compiler] No way to access to a private instance field from an enum method
Summary: [1.5][compiler] No way to access to a private instance field from an enum method
Status: RESOLVED INVALID
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.2   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.2 M3   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-10-04 06:02 EDT by Rémi Forax CLA
Modified: 2005-10-06 04:27 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Rémi Forax CLA 2005-10-04 06:02:36 EDT
The following code doesn't compile even if the JLS says
"class body is governed by the usual rule of anonymous classes".
page 255, chapter 8.9.".

public enum EnumInitBlock {
  max {
   { 
     val=3;  
   }         
   @Override public String toString() {
     return Integer.toString(val);
   }
  }; 
  {
    val=2;
  }
  private int val; 
  public static void main(String[] args) {
    System.out.println(max); // 3
  }
}

Rémi Forax

PS: i've reported the same bug to Sun.
Comment 1 Olivier Thomann CLA 2005-10-04 18:11:18 EDT
Could you please provide the reference in the Sun bug database?
Comment 2 Rémi Forax CLA 2005-10-05 02:48:40 EDT
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6332253

but the bug is currently not available

Rémi Forax
Comment 3 Philipe Mulet CLA 2005-10-05 05:10:08 EDT
I do not see any contradiction with the spec in our current behavior. Consider
the following example with anonymous type, it is still invalid:

class XY {
	static void foo() {
		new XY() {
			int field = val;
		};
	}
	private int val;
}

Problem comes from the fact you made the #val field private. By doing so, it is
no longer inherited, and rather needs to be accessed through the enclosing
instance. Now, because the method is static, it cannot reach the enclosing
instance, thus the error message you obtain.

In the case of an enum, enum constants are implicitly static, thus yielding the
same diagnosis. 

The enum testcase is essentially equivalent to the following code below.

public class EnumInitBlock {
  final static EnumInitBlock max = new EnumInitBlock(){
   { 
     val=3;  
   }         
  }; 
  private int val; 
}
Comment 4 Philipe Mulet CLA 2005-10-05 05:10:34 EDT
Closing as invalid.
Comment 5 Philipe Mulet CLA 2005-10-05 05:18:12 EDT
Added EnumTest#test124
Comment 6 Rémi Forax CLA 2005-10-05 11:57:50 EDT
Ok, i agree with your explaination with anonymous class.

It's not fully logic for me because :
  - if the val is not private, the code works
  - all the code are in the same compilation unit.

But if i have a bug to report, it's against the 
way anonymous class are describe by the JLS.

I'm not agree with the error reported.
If you prefix val by "this.", the compiler report the error
as "The field EnumInitBlock.val is not visible"
This error seems better for me.
Comment 7 Philipe Mulet CLA 2005-10-06 04:27:31 EDT
The reason for confusion is that you inherit the field and may reach it through
enclosing instance.
However, by making it private you cannot inherited it anymore. The fact it is in
same unit doesn't change it. Only enclosing accesses are emulated through
synthetics; only as long as there is a way to reach the enclosing instance,
which the static context prevents you from.

When you explicitly states "this.val", then you indicate you want the inherited
field (as opposed to enclosing), and thus you hit the visibility issue.

I agree the message isn't optimal in original case, because it is unclear to end
user there is some static context involved in there. Enum constants are only
implicitly static.