FULL PRODUCT VERSION :
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) 64-Bit Server VM (build 16.3-b01, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux <hostname> 2.6.24-gg804010-generic #1 SMP Mon Mar 1 13:59:15 PST 2010 x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
javac is at least not consistent in handling methods defined on enum constants. Its behavior depends on whether the compilation is against the source or class.
I have an interface with a method, enum implementing that interface, enum constant with class body implementing the method. If I call that method in another class javac gives an error. Here is the minimal example I came up with:
$ cat I.java
public interface I {
int compare();
}
$ cat X.java
public enum X implements I {
EQUAL() {
public int compare() { return 0; }
},
}
$ cat Y.java
public class Y {
int a() { return X.E.EQUAL.compare(); }
}
$ javac Y.java
Y.java:2: cannot find symbol
symbol : method compare()
location: class X
int a() { return X.EQUAL.compare(); }
^
1 error
However if I do:
$ javac X.java
$ javac Y.java
the compilation succeeds.
JLS section 8.9 says:
Instance methods declared in these class bodies are may be invoked outside the enclosing enum type only if they override accessible methods in the enclosing enum type.
I am not 100% sure how to read this. Usually accessible methods search includes superclasses and superinterfaces. It could be interpreted as accessible methods *defined* in the enclosing enum type itself (excluding superclasses and superinterfaces).
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
rm -f *.class
javac Y.java
observe error
rm -f *.class
javac X.java
javac Y.java
do not observe error
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Two ways to compile should at least have same result.
I would also like to have an official opinion how I shall interpret JLS in this case and expect compilation to implement that behavior.
ACTUAL -
Two ways to compile produce different result.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Y.java:2: cannot find symbol
symbol : method compare()
location: class X
int a() { return X.EQUAL.compare(); }
^
1 error
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
$ cat I.java
public interface I {
int compare();
}
$ cat X.java
public enum X implements I {
EQUAL() {
public int compare() { return 0; }
},
}
$ cat Y.java
public class Y {
int a() { return X.E.EQUAL.compare(); }
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
I found two workarounds: adding public abstract int compare(); to X or casting X.E.EQUAL to I
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) 64-Bit Server VM (build 16.3-b01, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux <hostname> 2.6.24-gg804010-generic #1 SMP Mon Mar 1 13:59:15 PST 2010 x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
javac is at least not consistent in handling methods defined on enum constants. Its behavior depends on whether the compilation is against the source or class.
I have an interface with a method, enum implementing that interface, enum constant with class body implementing the method. If I call that method in another class javac gives an error. Here is the minimal example I came up with:
$ cat I.java
public interface I {
int compare();
}
$ cat X.java
public enum X implements I {
EQUAL() {
public int compare() { return 0; }
},
}
$ cat Y.java
public class Y {
int a() { return X.E.EQUAL.compare(); }
}
$ javac Y.java
Y.java:2: cannot find symbol
symbol : method compare()
location: class X
int a() { return X.EQUAL.compare(); }
^
1 error
However if I do:
$ javac X.java
$ javac Y.java
the compilation succeeds.
JLS section 8.9 says:
Instance methods declared in these class bodies are may be invoked outside the enclosing enum type only if they override accessible methods in the enclosing enum type.
I am not 100% sure how to read this. Usually accessible methods search includes superclasses and superinterfaces. It could be interpreted as accessible methods *defined* in the enclosing enum type itself (excluding superclasses and superinterfaces).
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
rm -f *.class
javac Y.java
observe error
rm -f *.class
javac X.java
javac Y.java
do not observe error
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Two ways to compile should at least have same result.
I would also like to have an official opinion how I shall interpret JLS in this case and expect compilation to implement that behavior.
ACTUAL -
Two ways to compile produce different result.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Y.java:2: cannot find symbol
symbol : method compare()
location: class X
int a() { return X.EQUAL.compare(); }
^
1 error
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
$ cat I.java
public interface I {
int compare();
}
$ cat X.java
public enum X implements I {
EQUAL() {
public int compare() { return 0; }
},
}
$ cat Y.java
public class Y {
int a() { return X.E.EQUAL.compare(); }
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
I found two workarounds: adding public abstract int compare(); to X or casting X.E.EQUAL to I
- duplicates
-
JDK-6724345 incorrect method resolution for enum classes entered as source files
-
- Closed
-