I have three java types as defined below:
Main.java:
import java.util.Arrays;
import java.util.List;
public class Main
{
private Object callFunction()
{
OperationDefinitions func = OperationDefinitions.CONCATENATE;
List<Object> values = Arrays.asList(new Object[] {"ABC", "-", "DEF"});
return func.call (values);
}
public static void main (String[] args)
{
Main main = new Main();
System.out.println (main.callFunction());
}
}
Operation.java
import java.util.List;
public interface Operation
{
abstract Object call(List<Object> params);
}
OperationDefinitions.java
import java.util.List;
enum OperationDefinitions implements Operation
{
CONCATENATE() {
public Object call(List<Object> params)
{
StringBuilder builder = new StringBuilder();
for (Object param : params) builder.append((String)param);
return builder.toString();
}
},
;
}
(This is almost exactly the example given in Effective Java 2nd ed. Item 30) The code above compiles and runs just fine in eclipse, but with Sun javac I get the following error:
Main.java:12: cannot find symbol
symbol : method call(java.util.List<java.lang.Object>)
location: class OperationDefinitions
return func.call (values);
^
1 error
If I change line 12 of Main.java from return func.call(values);
to return ((Operation)func).call(values)
it compiles fine. Furthermore, if I put the three types (Operation, Main and OperationDefinitions) together as three subclasses of a single main class, it compiles fine as well.
So I do have workarounds for my problem, but I do wonder, why does javac require a cast here, but eclipse doesn't? Is this a bug in javac or in eclipse?
I've tried both Sun javac 1.5.0_19 and 1.6.0_16
Could this be Bug 6522780?
Or Bug 6330385?
Or Bug 6724345 - fixed in JDK 7 - so you could test that.
It might be a bug in Sun's javac. func
is an enum
(even if that enum
implements Operation
) and the Enum
class doesn't have a method call()
. To solve the issue, I suggest to change the assignment:
Operation func = OperationDefinitions.CONCATENATE;
That will also make it clear what you expect: An operation, not an enum
. The enum
is just a convenient way to collect all possible operations (a container if you wish).
This is a bug, as "Stephen Denne" has showed us, but if you can't do the update to a new version (but should)... Just remove the inteface from OperationDefinitions
and put the method ...call(...)
at the enum, like this:
public abstract Object call(List params);
Should work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With