Java equivalente aos methods de extensão C #

Eu estou olhando para implementar uma funcionalidade em uma lista de objects como eu faria em c # usando um método de extensão.

Algo assim:

List list; // ... List initialization. list.getData(id); 

Como faço isso em Java?

Java não suporta methods de extensão.

Em vez disso, você pode criar um método estático regular ou escrever sua própria class.

Os methods de extensão não são apenas methods estáticos e não apenas açúcar de syntax de conveniência, na verdade, são ferramentas bastante poderosas. A principal coisa é a capacidade de replace methods diferentes com base na instanciação de parâmetros de genéricos diferentes. Isso é semelhante a classs de tipo do Haskell e, na verdade, parece que eles estão em c # para oferecer suporte a Monads do C # (ou seja, LINQ). Mesmo descartando a syntax do LINQ, ainda não sei como implementar interfaces semelhantes em Java.

E eu não acho que é possível implementá-los em Java, por causa da semântica de exclusão de tipo genérico de parâmetros do Java.

O projeto Lombok fornece uma anotação @ExtensionMethod que pode ser usada para obter a funcionalidade que você está solicitando.

A linguagem XTend – que é um super conjunto de Java e compila para o código-fonte Java 1 – suporta isso.

Java não tem esse recurso. Em vez disso, você pode criar uma subclass regular de sua implementação de lista ou criar uma class interna anônima:

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

O problema é chamar esse método. Você pode fazer isso “no lugar”:

 new ArrayList() { public String getData() { return ""; // add your implementation here. } }.getData(); 

Outra opção é usar as classs ForwardingXXX da biblioteca google-goava.

Parece haver uma pequena chance de que o Defender Methods (isto é, methods padrão) possa transformá-lo no Java 8. No entanto, até onde eu entendo, eles só permitem que o autor de uma interface estenda retroativamente, não usuários arbitrários.

O Defender Methods + Interface Injection seria então capaz de implementar totalmente os methods de extensão no estilo C #, mas o AFAICS, Interface Injection ainda não está no mapa rodoviário do Java 8.

O Manifold fornece methods de extensão no estilo Java com C # e vários outros resources. Ao contrário de outras ferramentas, o Manifold não tem limitações e não sofre com problemas com genéricos, lambdas, IDE etc. O Manifold fornece vários outros resources, como tipos personalizados estilo F #, interfaces estruturais no estilo TypeScript e tipos expando no estilo Javascript.

Além disso, o IntelliJ fornece suporte abrangente para o Manifold por meio do plug-in Manifold.

O Manifold é um projeto de código aberto disponível no github .

Pouco tarde para a parte sobre esta questão, mas no caso de alguém achar útil eu acabei de criar uma subclass:

 public class ArrayList2 extends ArrayList { private static final long serialVersionUID = 1L; public T getLast() { if (this.isEmpty()) { return null; } else { return this.get(this.size() - 1); } } } 

Pode-se usar o padrão de design orientado a objects do decorador . Um exemplo desse padrão sendo usado na biblioteca padrão do Java seria o DataOutputStream .

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

 public class ListDecorator implements List { public final List wrapee; public ListDecorator(List wrapee) { this.wrapee = wrapee; } // implementation of all the list's methods here... public  ListDecorator map(Transform transformer) { ArrayList result = new ArrayList(size()); for (E element : this) { R transformed = transformer.transform(element); result.add(transformed); } return new ListDecorator(result); } } 

PS Sou um grande fã de Kotlin . Tem methods de extensão e também é executado na JVM.

Tecnicamente, o C # Extension não tem equivalente em Java. Mas se você quiser implementar essas funções para um código mais limpo e capacidade de manutenção, você tem que usar o framework 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(); } } 

Java 8 agora suporta methods padrão , que são semelhantes aos methods de extensão do C# .