Я ищу для реализации функциональности в списке объектов, как я бы в C #, используя метод расширения.
Что-то вроде этого:
List<DataObject> list;
// ... List initialization.
list.getData(id);
Как мне это сделать на Java?
java
extension-methods
Фабио Мильейру
источник
источник
Ответы:
Java не поддерживает методы расширения.
Вместо этого вы можете создать обычный статический метод или написать свой собственный класс.
источник
Методы расширения - это не просто статический метод и не просто удобство синтаксиса, на самом деле это довольно мощный инструмент. Главное, что есть возможность переопределять разные методы, основанные на создании экземпляров различных родовых параметров. Это похоже на классы типов в Haskell, и, на самом деле, похоже, что они находятся в C # для поддержки монад C # (т.е. LINQ). Даже отбрасывая синтаксис LINQ, я до сих пор не знаю способа реализации подобных интерфейсов в Java.
И я не думаю, что возможно реализовать их в Java, из-за семантики стирания типов Java обобщенных параметров.
источник
Проект Ломбок предоставляет аннотацию,
@ExtensionMethod
которую можно использовать для достижения требуемой функциональности.источник
java.lang.String
. Демонстрация: http://manifold.systems/images/ExtensionMethod.mp4Технически расширение C # не имеет аналогов в Java. Но если вы хотите реализовать такие функции для более чистого кода и удобства сопровождения, вы должны использовать платформу Manifold.
источник
Язык XTend - который является супернабором Java и компилируется в исходный код Java 1 - поддерживает это.
источник
Коллектор предоставляет Java методы расширения в стиле C # и ряд других функций. В отличие от других инструментов, Manifold не имеет ограничений и не страдает от проблем с обобщениями, лямбдами, IDE и т. Д. Manifold предоставляет несколько других функций, таких как настраиваемые типы в стиле F # , структурные интерфейсы в стиле TypeScript и расширяемые типы в стиле Javascript .
Кроме того, IntelliJ обеспечивает всестороннюю поддержку Manifold через плагин Manifold .
Manifold - это проект с открытым исходным кодом, доступный на github .
источник
Другой вариант - использовать классы ForwardingXXX из библиотеки google-guava.
источник
У Java нет такой возможности. Вместо этого вы можете либо создать обычный подкласс вашей реализации списка, либо создать анонимный внутренний класс:
Проблема в том, чтобы вызвать этот метод. Вы можете сделать это "на месте":
источник
Похоже , есть некоторые небольшие шансы , что Защитник метода (т.е. метода по умолчанию) может сделать это в Java 8. Однако, насколько я понимаю их, они лишь позволяют автор в
interface
заднем числе продлить его, а не произвольные пользователь.Методы Defender + Interface Injection смогут полностью реализовать методы расширения в стиле C #, но AFAICS, Interface Injection даже не входит в план развития Java 8.
источник
Немного опоздал на вечеринку по этому вопросу, но на тот случай, если кто-то сочтет это полезным, я просто создал подкласс
источник
Мы можем смоделировать реализацию методов расширения C # в Java, используя реализацию метода по умолчанию, доступную начиная с Java 8. Мы начнем с определения интерфейса, который позволит нам получить доступ к объекту поддержки через метод base (), например, так:
Мы возвращаем null, так как интерфейсы не могут иметь состояния, но это должно быть исправлено позже через прокси.
Разработчик расширений должен был бы расширить этот интерфейс новым интерфейсом, содержащим методы расширения. Допустим, мы хотим добавить потребителя forEach в интерфейс List:
Поскольку мы расширяем интерфейс Extension, мы можем вызвать метод base () внутри нашего метода extension, чтобы получить доступ к объекту поддержки, к которому мы присоединяемся.
Интерфейс Extension должен иметь фабричный метод, который создаст расширение данного объекта поддержки:
Мы создаем прокси, который реализует интерфейс расширения и весь интерфейс, реализованный по типу объекта поддержки. Обработчик вызова, данный прокси, будет отправлять все вызовы к объекту поддержки, за исключением «базового» метода, который должен возвращать объект поддержки, в противном случае его реализация по умолчанию возвращает нуль:
Затем мы можем использовать метод Extension.create (), чтобы присоединить интерфейс, содержащий метод расширения, к объекту поддержки. Результатом является объект, который может быть приведен к интерфейсу расширения, с помощью которого мы все еще можем получить доступ к объекту поддержки, вызывающему метод base (). Получив ссылку на интерфейс расширения, мы теперь можем безопасно вызывать методы расширения, которые могут иметь доступ к объекту поддержки, чтобы теперь мы могли присоединять новые методы к существующему объекту, но не к его определяющему типу:
Таким образом, это способ, которым мы можем имитировать способность расширять объекты в Java, добавляя к ним новые контракты, что позволяет нам вызывать дополнительные методы для указанных объектов.
Ниже вы можете найти код интерфейса расширения:
источник
Можно было бы использовать декоратор объектно-ориентированного шаблона проектирования . Примером этого шаблона, используемого в стандартной библиотеке Java, может быть DataOutputStream .
Вот некоторый код для расширения функциональности списка:
PS Я большой поклонник Kotlin . У него есть методы расширения, а также он работает на JVM.
источник
Вы можете создать C # -подобный метод расширения / помощника путем (RE) реализации интерфейса Collections и добавления-примера для Java Collection:
источник
Java
8 теперь поддерживает методы по умолчанию , которые похожи наC#
методы расширения.источник