有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java javac抱怨:在enum实现接口上找不到符号

我有三种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());
    }
}

手术。爪哇

import java.util.List;

public interface Operation
{
    abstract Object call(List<Object> params);
}

操作定义。爪哇

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

}

(这几乎正是有效Java第二版第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

如果我换了第12行的话。java从return func.call(values);return ((Operation)func).call(values)它编译得很好。此外,如果我将这三种类型(Operation、Main和OperationDefinitions)作为一个主类的三个子类放在一起,它的编译效果也很好

所以我确实有解决问题的方法,但我确实想知道,为什么javac在这里需要强制转换,而eclipse不需要?这是javac中的bug还是eclipse中的bug

我已经试过Sun Java 1.5.0_19和1.6.0_16


共 (4) 个答案

  1. # 2 楼答案

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

    其中一个部分原因是,据我所知,接口中定义的所有方法都必须是公共的。如果您真的在带有默认访问修饰符的接口中定义了call方法,我希望编译器会拒绝它——但如果它没有这样做,那么看到后续问题也不会让我感到惊讶。如果这是一个打字错误,那么很好,但是如果你的代码是这样的,试着把它声明为公共的,看看问题是否消失了

  2. # 3 楼答案

    这可能是Sun的javac中的一个bugfunc是一个enum(即使该enum实现了Operation),并且Enum类没有方法call()。为了解决这个问题,我建议更改作业:

    Operation func = OperationDefinitions.CONCATENATE;
    

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

  3. # 4 楼答案

    正如“Stephen Denne”向我们展示的,这是一个bug,但是如果您不能更新到新版本(但应该)。。。只需从OperationDefinitions中删除接口,并将方法...call(...)放在枚举中,如下所示:

    public abstract Object call(List params);

    应该有用