Java эквивалентен методам расширения C # - PullRequest
159 голосов
/ 05 декабря 2010

Я хочу реализовать функциональность в списке объектов, как в C #, используя метод расширения.

Примерно так:

List<DataObject> list;
// ... List initialization.
list.getData(id);

Как мне это сделать вJava

Ответы [ 12 ]

176 голосов
/ 05 декабря 2010

Java не поддерживает методы расширения.

Вместо этого вы можете создать обычный статический метод или написать собственный класс.

50 голосов
/ 05 января 2015

Методы расширения - это не просто статический метод и не просто удобство синтаксиса, на самом деле это довольно мощный инструмент. Главное, что есть возможность переопределять разные методы, основываясь на различных экземплярах универсальных параметров. Это похоже на классы типов в Haskell, и, на самом деле, похоже, что они находятся в C # для поддержки монад C # (т.е. LINQ). Даже если отбросить синтаксис LINQ, я все еще не знаю способа реализации подобных интерфейсов в Java.

И я не думаю, что возможно реализовать их в Java из-за семантики стирания типов Java обобщенных параметров.

15 голосов
/ 22 мая 2015

Project Lombok предоставляет аннотацию @ExtensionMethod, которую можно использовать для достижения требуемой функциональности.

7 голосов
/ 16 апреля 2014

Язык XTend & mdash; который является супер-набором Java и компилируется в исходный код Java 1 & mdash; поддерживает это.

6 голосов
/ 28 декабря 2010

Другой вариант - использовать ForwardingXXX классы из библиотеки google-guava.

6 голосов
/ 05 декабря 2010

Java не имеет такой функции.Вместо этого вы можете либо создать обычный подкласс вашей реализации списка, либо создать анонимный внутренний класс:

List<String> list = new ArrayList<String>() {
   public String getData() {
       return ""; // add your implementation here. 
   }
};

Проблема заключается в вызове этого метода.Вы можете сделать это "на месте":

new ArrayList<String>() {
   public String getData() {
       return ""; // add your implementation here. 
   }
}.getData();
5 голосов
/ 27 июля 2018

Технически расширение C # не имеет аналогов в Java. Но если вы хотите реализовать такие функции для более чистого кода и удобства сопровождения, вы должны использовать платформу Manifold.

package extensions.java.lang.String;

import manifold.ext.api.*;

@Extension
public class MyStringExtension {

  public static void print(@This String thiz) {
    System.out.println(thiz);
  }

  @Extension
  public static String lineSeparator() {
    return System.lineSeparator();
  }
}
5 голосов
/ 25 февраля 2018

Коллектор предоставляет Java с C # -стилем методы расширения и ряд других функций.В отличие от других инструментов, Manifold не имеет ограничений и не страдает от проблем с обобщениями, лямбдами, IDE и т. Д. В Manifold есть несколько других функций, таких как F # -тиль пользовательские типы , стиль TypeScript структурные интерфейсы и Javascript-стиль расширенные типы .

Кроме того, IntelliJ обеспечивает всестороннюю поддержку коллектора с помощью плагина Manifold .

Manifold - это проект с открытым исходным кодом, доступный на github .

4 голосов
/ 05 декабря 2010

Похоже, есть небольшой шанс, что Методы Защитника (то есть методы по умолчанию) могут превратиться в Java 8. Однако, насколько я понимаю, они позволяют author из * 1003. * задним числом расширить его, а не произвольных пользователей.

Defender Methods + Interface Injection сможет полностью реализовать методы расширения в стиле C #, но AFAICS, Interface Injection даже не входит в план развития Java 8.

3 голосов
/ 31 июля 2012

Немного опоздал на вечеринку по этому вопросу, но в случае, если кто-то посчитает это полезным, я просто создал подкласс:

public class ArrayList2<T> extends ArrayList<T> 
{
    private static final long serialVersionUID = 1L;

    public T getLast()
    {
        if (this.isEmpty())
        {
            return null;
        }
        else
        {       
            return this.get(this.size() - 1);
        }
    }
}
...