Eu estou olhando para implementar uma funcionalidade em uma lista de objetos como faria em C # usando um método de extensão.
Algo assim:
List<DataObject> list;
// ... List initialization.
list.getData(id);
Como faço isso em Java?
java
extension-methods
Fabio Milheiro
fonte
fonte
Respostas:
Java não suporta métodos de extensão.
Em vez disso, você pode criar um método estático regular ou escrever sua própria classe.
fonte
Os métodos de extensão não são apenas métodos estáticos e não apenas açúcar de sintaxe de conveniência, na verdade eles são uma ferramenta bastante poderosa. O principal é a capacidade de substituir métodos diferentes com base na instanciação de parâmetros de genéricos diferentes. Isso é semelhante às classes de tipo de Haskell e, de fato, parece que elas estão em C # para suportar as mônadas de C # (ou seja, LINQ). Mesmo eliminando a sintaxe do LINQ, ainda não conheço nenhuma maneira de implementar interfaces semelhantes em Java.
E não creio que seja possível implementá-los em Java, devido à semântica de apagamento de tipo de Java dos parâmetros genéricos.
fonte
O Projeto Lombok fornece uma anotação
@ExtensionMethod
que pode ser usada para obter a funcionalidade que você está solicitando.fonte
java.lang.String
,. Demonstração: http://manifold.systems/images/ExtensionMethod.mp4Tecnicamente, a extensão C # não tem equivalente em Java. Mas se você deseja implementar essas funções para obter um código e uma manutenção mais limpos, use a estrutura do Manifold.
fonte
A linguagem XTend - que é um superconjunto de Java e compila no código-fonte 1 do Java - suporta isso.
fonte
O Manifold fornece ao Java métodos de extensão no estilo C # e vários outros recursos. Diferentemente de outras ferramentas, o Manifold não tem limitações e não sofre problemas com genéricos, lambdas, IDE etc. O Manifold fornece vários outros recursos, como tipos personalizados no estilo F # , interfaces estruturais no estilo TypeScript e tipos expando no estilo Javascript .
Além disso, o IntelliJ fornece suporte abrangente ao Manifold por meio do plug-in do Manifold .
Manifold é um projeto de código aberto disponível no github .
fonte
Outra opção é usar as classes ForwardingXXX da biblioteca do google-goiaba.
fonte
Java não possui esse recurso. Em vez disso, você pode criar subclasses regulares da implementação da sua lista ou criar uma classe interna anônima:
O problema é chamar esse método. Você pode fazer isso "no lugar":
fonte
Parece que há uma pequena chance de que os Métodos Defender (ou seja, métodos padrão) possam entrar no Java 8. No entanto, até onde eu os entendo, eles permitem apenas que o autor de um
interface
estenda-o retroativamente, e não usuários arbitrários.O Defender Methods + Interface Injection seria capaz de implementar completamente os métodos de extensão no estilo C #, mas o AFAICS, Interface Injection ainda não está no roteiro do Java 8.
fonte
Um pouco atrasado para a parte sobre esta questão, mas, caso alguém ache útil, acabei de criar uma subclasse:
fonte
Podemos simular a implementação dos métodos de extensão C # em Java usando a implementação padrão disponível desde o Java 8. Começamos definindo uma interface que nos permitirá acessar o objeto de suporte por meio de um método base (), como:
Retornamos nulos, pois as interfaces não podem ter estado, mas isso deve ser corrigido posteriormente por meio de um proxy.
O desenvolvedor de extensões teria que estender essa interface por uma nova interface contendo métodos de extensão. Digamos que queremos adicionar um consumidor forEach na interface List:
Como estendemos a interface Extension, podemos chamar o método base () dentro do nosso método de extensão para acessar o objeto de suporte ao qual anexamos.
A interface Extension deve ter um método de fábrica que criará uma extensão de um determinado objeto de suporte:
Criamos um proxy que implementa a interface de extensão e toda a interface implementada pelo tipo do objeto de suporte. O manipulador de chamada fornecido ao proxy enviaria todas as chamadas para o objeto de suporte, exceto o método "base", que deve retornar o objeto de suporte, caso contrário, sua implementação padrão retornará nulo:
Em seguida, podemos usar o método Extension.create () para anexar a interface que contém o método de extensão ao objeto de suporte. O resultado é um objeto que pode ser convertido para a interface de extensão pela qual ainda podemos acessar o objeto de suporte que chama o método base (). Tendo a referência convertida para a interface de extensão, agora podemos chamar com segurança os métodos de extensão que podem ter acesso ao objeto de suporte, para que agora possamos anexar novos métodos ao objeto existente, mas não ao seu tipo de definição:
Portanto, é uma maneira de simular a capacidade de estender objetos em Java adicionando novos contratos a eles, o que nos permite chamar métodos adicionais para os objetos fornecidos.
Abaixo, você pode encontrar o código da interface Extension:
fonte
Pode-se usar o padrão de design orientado a objetos do decorador . Um exemplo desse padrão usado na biblioteca padrão de Java seria o DataOutputStream .
Aqui está um código para aumentar a funcionalidade de uma lista:
PS Eu sou um grande fã de Kotlin . Possui métodos de extensão e também é executado na JVM.
fonte
Você pode criar um método de extensão / auxiliar do tipo C # implementando a interface Collections e adicionando um exemplo para o Java Collection:
fonte
Java
8 agora suporta métodos padrão , que são semelhantes aosC#
métodos de extensão.fonte