Java equivalente aos métodos de extensão c#

eu estou procurando implementar uma funcionalidade em uma lista de objetos como eu faria em C# usando um método de extensão.

Algo do género:
List<DataObject> list;
// ... List initialization.
list.getData(id);
Como faço isso em Java?

Author: Fabio Milheiro, 2010-12-05

12 answers

O Java não suporta Métodos de extensão.

Em vez disso, você pode fazer um método estático regular, ou escrever sua própria classe.
 155
Author: SLaks, 2010-12-05 17:01:33

Os Métodos de extensão não são apenas métodos estáticos e não apenas açúcar sintaxe de conveniência, na verdade eles são uma ferramenta bastante poderosa. O principal é a capacidade de substituir diferentes métodos baseados na instanciação de parâmetros genéricos diferentes. Isto é semelhante ao tipo de classes de Haskell, e na verdade, parece que eles estão em C# para suportar os Monads de c#(i.e. LINQ). Mesmo lançando a sintaxe LINQ, eu ainda não sei nenhuma maneira de implementar interfaces semelhantes em Java.

E eu não acho é possível implementá-los em Java, por causa da semântica de tipo erasure de parâmetros genéricos.
 38
Author: user1686250, 2016-07-14 17:57:39

O projecto Lombok fornece uma anotação @ExtensionMethod isso pode ser usado para alcançar a funcionalidade que você está pedindo.

 12
Author: Thomas Eizinger, 2015-05-22 20:49:18

A Linguagem XTend - que é um super-conjunto de Java, e compila para código fonte Java1 - apoia isto.

 7
Author: Sam Keays, 2015-12-22 18:14:01

Java não tem esse recurso. Em vez disso, poderá criar uma subclasse regular da implementação da sua lista ou criar uma classe interna anónima:

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

O problema é chamar este método. Você pode fazer "no lugar":

new ArrayList<String>() {
   public String getData() {
       return ""; // add your implementation here. 
   }
}.getData();
 6
Author: AlexR, 2013-01-08 07:01:05

Outra opção é usar Forwardingxx classes da biblioteca google-guava.

 6
Author: Aravind R. Yarram, 2016-06-01 10:26:11

Parece que há uma pequena possibilidade de que os métodos default (ou seja, os métodos padrão) possam torná-lo em Java 8. No entanto, tanto quanto eu os entendo, eles só permitem que o Autor de um interface a estender retroativamente, não usuários arbitrários.

Defender Methods + Interface Injection would then be able to fully implement C# - style extension methods, but AFAICS, Interface Injection isn't even on the Java 8 road-map yet.

 4
Author: Jörg W Mittag, 2015-12-22 18:20:14

Manifold fornece Java com C# - style métodos de extensão e várias outras funcionalidades. Ao contrário de outras ferramentas, Variold não tem limitações e não sofre de problemas com genéricos, lambdas, IDE etc. O Manifold oferece várias outras funcionalidades, tais como F#-style tipos personalizados, TypeScript-style interfaces estruturais, e Javascript-style expando types.

Além disso, a Intelij fornece um suporte abrangente para múltiplos via o plugin do Manifold .

O Manifold é um projecto de código aberto disponível em github .

 4
Author: Scott McKinney, 2018-02-25 19:12:33
Um pouco tarde para o partido nesta questão,mas no caso de alguém achar útil, acabei de criar uma subclasse:
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);
        }
    }
}
 3
Author: magritte, 2012-07-31 19:28:14

Tecnicamente a extensão C# não tem equivalente em Java. Mas se você quer implementar tais funções para um código mais limpo e mantenibilidade, você tem que usar framework Variold.

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();
  }
}
 2
Author: M.Laida, 2018-07-27 07:01:15

Pode-se usar o Modelo de desenho orientado a objectos. Um exemplo deste padrão sendo usado na Biblioteca Padrão de Java seria o DataOutputStream .

Aqui está um código para aumentar a funcionalidade de uma lista:

public class ListDecorator<E> implements List<E>
{
    public final List<E> wrapee;

    public ListDecorator(List<E> wrapee)
    {
        this.wrapee = wrapee;
    }

    // implementation of all the list's methods here...

    public <R> ListDecorator<R> map(Transform<E,R> transformer)
    {
        ArrayList<R> result = new ArrayList<R>(size());
        for (E element : this)
        {
            R transformed = transformer.transform(element);
            result.add(transformed);
        }
        return new ListDecorator<R>(result);
    }
}

P. S. sou um grande fã de Kotlin. Tem métodos de extensão e também funciona na JVM.

 1
Author: Eric, 2016-07-25 21:36:02

Java 8 agora suporta métodos predefinidos, que são semelhantes aos métodos de extensão de C#.

 -7
Author: DarVar, 2015-12-22 18:09:19