javac жалуется: не могу найти символ в интерфейсе реализации enum - PullRequest
15 голосов
/ 02 октября 2009

У меня есть три типа 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. Item 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 файла Main.java с return func.call(values); на return ((Operation)func).call(values), он прекрасно скомпилируется. Более того, если я соберу три типа (Operation, Main и OperationDefinitions) вместе как три подкласса одного основного класса, он также хорошо скомпилируется.

Так что у меня есть обходные пути для моей проблемы, но я удивляюсь, почему javac требует здесь приведение, а затмение - нет? Это ошибка в javac или в eclipse?

Я пробовал и Sun javac 1.5.0_19 и 1.6.0_16

Ответы [ 4 ]

14 голосов
/ 02 октября 2009

Может ли это быть Ошибка 6522780 ?
Или Ошибка 6330385 ?
Или Ошибка 6724345 - исправлена ​​в JDK 7 - чтобы вы могли проверить это.

10 голосов
/ 02 октября 2009

Это может быть ошибка в javac Sun. func - это enum (даже если enum реализует Operation), а класс Enum не имеет метода call(). Для решения проблемы предлагаю изменить назначение:

Operation func = OperationDefinitions.CONCATENATE;

Это также прояснит, что вы ожидаете: операция, а не enum. enum - это просто удобный способ собрать все возможные операции (контейнер, если хотите).

2 голосов
/ 04 декабря 2013

Это ошибка, как показал нам Стивен Денн, но если вы не можете выполнить обновление до новой версии (но должно это сделать) ... Просто удалите интерфейс из OperationDefinitions и поместите метод ...call(...) в перечислении, вот так:

public abstract Object call(List params);

Должно работать.

0 голосов
/ 02 октября 2009

Я подозреваю, что это действительно ошибка в javac; OperationDefinitions определенно имеет вызов (абстрактного) метода (java.util.List), поскольку он реализует интерфейс Operation. И определение класса является допустимым, поскольку все константы обеспечивают конкретную реализацию этого интерфейса.

Одна вещь, которая может частично отвечать за это, это то, что, насколько мне известно, все методы, определенные в интерфейсе, должны быть открытыми. Если вы действительно определили метод call в интерфейсе с модификатором доступа по умолчанию, я бы ожидал, что компилятор отклонит его - но если этого не произойдет, меня не удивит появление проблем в будущем. Если это опечатка, тогда хорошо, но если это так в вашем коде, попробуйте объявить его публичным и посмотреть, исчезнет ли проблема.

...