Экземпляр объекта без интерфейса реализации

Пожалуйста, посмотрите этот код:

public interface Worker {
    void work(double a);
}

public class Employee {
    public static void test() {
        System.out.println("Test");
    }

    public static void test(double a) {
        System.out.println("Number : " + a);
    }
}

public class MainClass {
    public static void main(String[] args) {
         Worker w = Employee::test;
         w.work(12);
    }
}

Как можно создать новый объект Employee в качестве интерфейса Worker без его реализации?

Интерфейс имеет только один метод, поэтому он является функциональным интерфейсом и может быть реализован с помощью лямбды. Лямбда — это «объект», который вы ищете.

Turing85 26.08.2024 18:53

Вы имеете в виду, что это лямбда-функция?

mah454 26.08.2024 18:54

@Turing85: Turing85: Здесь нет лямбда-выражений - только ссылка на метод. (Вы можете использовать лямбду для реализации функционального интерфейса, но этот код этого не делает.)

Jon Skeet 26.08.2024 18:54

Ваш вопрос не имеет никакого смысла. Пожалуйста, объясните немного больше, чего вы на самом деле хотите. Вы можете реализовать интерфейс Worker без реализации какого-либо класса: Worker w = a -> a * 2; или даже Worker w = a -> {System.out.println("Worker working..."); return a * 2;};. Но зачем вам тогда Employee в вашем коде или позволить Employee реализовать Worker? Мне кажется, вы там что-то путаете. Пожалуйста, исправьте свой вопрос.

JayC667 26.08.2024 18:58

@JayC667 JayC667, я читаю тот же код только в сообществе linkedin, меня это только смущает!

mah454 26.08.2024 19:00

@Turing85: Меня это сбивает с толку, учитывая, что фактическая спецификация определяет лямбда-выражения совершенно отдельно. Действительно, спецификация ссылок на методы включает (при обсуждении перегрузки): «Это должно удовлетворять подавляющему большинству случаев использования; когда возникает редкая необходимость в более точном управлении, можно использовать лямбда-выражение», что предполагает, что спецификация соответствует не рассматривать ссылки на методы как лямбда-выражения. Я бы предположил, что здесь спецификация более точна, а руководство просто запутано.

Jon Skeet 26.08.2024 19:38

@Turing85: Аналогичным образом, в разделе спецификации для лямбда-выражений есть: «Практически говоря, лямбда-выражению необычно говорить о себе (либо рекурсивно вызывать себя, либо вызывать другие методы), хотя чаще встречается хотите использовать имена для ссылки на элементы включающего класса, которые в противном случае были бы затенены (this, toString()). Если необходимо, чтобы лямбда-выражение ссылалось на себя (как если бы через this), ссылку на метод или анонимный объект. Вместо этого следует использовать внутренний класс». Опять же, это подсказывает мне различие между лямбда-выражениями и ссылками на методы.

Jon Skeet 26.08.2024 19:39

@JonSkeet, как бы вы ни разрезали пирог, ссылки на методы тесно связаны с функциональными интерфейсами и лямбда-выражениями. IIRC, есть также детали реализации, то есть то, что компилятор и среда выполнения делают с соответствующим выражением.

Turing85 26.08.2024 19:47

@Turing85: Они определенно связаны с функциональными интерфейсами. Я просто не вижу смысла мутить воду между лямбда-выражениями и ссылками на методы, хотя мне они кажутся совершенно разными способами достижения схожих целей. (С точки зрения C#, любой, кто ссылается на преобразование группы методов как на лямбда-выражение, наверняка будет совершенно неправ.) Грамматика LambdaExpression также полностью отличается от грамматики ссылок на методы. Зачем объединять эти два понятия?

Jon Skeet 26.08.2024 20:09

@JonSkeet То, что синтаксис другой, очевидно; как еще мы могли бы получить удобный способ написать «лямбду для уже существующего метода»? Сказать, что «у них разный синтаксис, следовательно, и разная семантика» — это w.l.o.g. неправильный. Лямбда-выражения и ссылки на методы используют одни и те же инструкции байт-кода. Поэтому я думаю, что объединение лямбда-выражений со ссылками на методы полезно, поскольку это один и тот же механизм. Я не уверен, какое значение имеет C#, поскольку пост посвящен Java.

Turing85 26.08.2024 20:41

@JonSkeet Если вам интересно, я могу предоставить пример, показывающий разницу в байт-коде между лямбда-выражением и ссылкой на метод.

Turing85 26.08.2024 20:41
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
13
63
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Экземпляров Employee не создано вообще. Вы используете ссылку на метод для реализации интерфейса Worker, который является функциональным интерфейсом из-за наличия только одного абстрактного метода.

Ссылка на метод Employee::test (перегрузка, принимающая параметр double) удовлетворяет этому функциональному интерфейсу, поэтому преобразование ссылки на метод в функциональный интерфейс завершается успешно.

Другие вопросы по теме