Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javac complains: cannot find symbol on enum implementing interface

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

like image 992
amarillion Avatar asked Oct 02 '09 09:10

amarillion


3 Answers

Could this be Bug 6522780?
Or Bug 6330385?
Or Bug 6724345 - fixed in JDK 7 - so you could test that.

like image 133
Stephen Denne Avatar answered Oct 27 '22 16:10

Stephen Denne


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).

like image 22
Aaron Digulla Avatar answered Oct 27 '22 16:10

Aaron Digulla


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.

like image 34
Miqueias Oliv. Gomes Avatar answered Oct 27 '22 15:10

Miqueias Oliv. Gomes