Nano Hash - криптовалюты, майнинг, программирование

javac жалуется: не удается найти символ в интерфейсе реализации enum

У меня есть три типа java, как определено ниже:

Основная.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());
    }
}

Операция.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();
        }
    },
    ;

}

(Это почти точно пример, приведенный в Эффективном 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 требует приведения здесь, а eclipse - нет? Это ошибка в javac или в eclipse?

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


Ответы:


1

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

02.10.2009
  • Похоже, это действительно ошибка 6724345. Спасибо! 02.10.2009

  • 2

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

    Operation func = OperationDefinitions.CONCATENATE;
    

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

    02.10.2009
  • +1 за стиль, обычно это было бы правильно. Что я здесь не объяснил, так это то, что это всего лишь небольшой фрагмент реального кода, а OperationDefinitions имеет дополнительные функции-члены, которых нет в Operation, например, getHelp() и getDescription(). 02.10.2009
  • Не говоря уже о том, что мы всегда должны программировать интерфейсы, а не классы! getHelp и getDesctiption должны быть определены в другом интерфейсе. Предположим, что у вас есть интерфейс вроде interface Helper {String getHelp(); String getDescription();} Таким образом, вы можете вызвать getHelp() следующим образом: Helper helper = OperationDefinitions.CONCATENATE; помощник.Помощь(); 22.11.2011

  • 3

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

    public abstract Object call(List params);

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

    04.12.2013

    4

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

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

    02.10.2009
  • Все методы в интерфейсе неявно абстрактны и общедоступны. Если вы опустите эти модификаторы (что рекомендуется AFAIK), компилятор добавит их за вас. Если вы напишете любой другой модификатор, вы получите ошибку. 02.10.2009
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..