javac complains: cannot find symbol on enum implementing interface

我怕爱的太早我们不能终老 提交于 2019-12-04 16:29:46

问题


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


回答1:


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




回答2:


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




回答3:


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.




回答4:


I suspect this is actually a bug in javac; OperationDefinitions definitely does have an (abstract) method call(java.util.List), since it implements the Operation interface. And the class definition is valid, since all constants provide a concrete implementation of this interface.

One thing that might be partially responsible for this, is that to my knowledge all methods defined in an interface must be public. If you've really defined the call method in the interface with the default access modifier, I'd expect the compiler to reject it - but if it doesn't then it wouldn't surprise me to see problems down the line. If this was a typo then fine, but if it's like that in your code try declaring it as public and seeing if the problem goes away.



来源:https://stackoverflow.com/questions/1508632/javac-complains-cannot-find-symbol-on-enum-implementing-interface

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!