javac抱怨:在枚举实现界面上找不到符号

时间:2009-10-02 09:43:54

标签: java interface casting enums javac

我有三种java类型,如下所示:

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();
        }
    },
    ;

}

(这几乎就是Effective Java 2nd ed中给出的例子。第30项) 上面的代码在eclipse中编译并运行得很好,但是使用Sun javac我得到以下错误:

Main.java:12: cannot find symbol
symbol  : method call(java.util.List<java.lang.Object>)
location: class OperationDefinitions
        return func.call (values);
                           ^
1 error

如果我将Main.java的第12行从return func.call(values);更改为return ((Operation)func).call(values),则编译正常。此外,如果我将三种类型(Operation,Main和OperationDefinitions)放在一起作为单个主类的三个子类,它也可以很好地编译。

所以我确实为我的问题找到了解决办法,但我确实想知道,为什么javac需要在这里进行投射,但是eclipse没有?这是javac或eclipse中的错误吗?

我已经尝试过Sun javac 1.5.0_19和1.6.0_16

4 个答案:

答案 0 :(得分:14)

这可能是Bug 6522780吗? 或Bug 6330385
或者Bug 6724345 - 在JDK 7中修复 - 所以你可以测试它。

答案 1 :(得分:10)

这可能是Sun的javac中的一个错误。 funcenum(即使enum实施Operation),Enum类没有方法call()。为解决这个问题,我建议更改作业:

Operation func = OperationDefinitions.CONCATENATE;

这也将明确你的期望:一个操作,而不是enumenum只是收集所有可能操作的便捷方式(如果您愿意,可以使用容器)。

答案 2 :(得分:2)

这是一个错误,正如“Stephen Denne”向我们展示的那样,但是如果你不能对新版本进行更新(但应该)......只需从OperationDefinitions删除界面并将其放入枚举中的方法...call(...),如下所示:

public abstract Object call(List params);

应该工作。

答案 3 :(得分:0)

我怀疑这实际上是javac中的一个错误; OperationDefinitions肯定确实有一个(抽象)方法调用(java.util.List),因为它实现了Operation接口。并且类定义是有效的,因为所有常量都提供了此接口的具体实现。

可能对此负有部分责任的一件事是,据我所知,界面中定义的所有方法都必须是公共的。如果你真的在接口中使用默认访问修饰符定义了call方法,我希望编译器拒绝它 - 但如果它没有,那么看到问题就不会让我感到惊讶线。如果这是一个错字然后很好,但如果它像你的代码中那样尝试将其声明为公开并查看问题是否消失。