Isso pode ser algo comum e trivial, mas parece que estou tendo problemas para encontrar uma resposta concreta. No C #, existe um conceito de delegados, que se relaciona fortemente com a idéia de ponteiros de função do C ++. Existe uma funcionalidade semelhante em Java? Dado que os indicadores estão um pouco ausentes, qual é a melhor maneira de fazer isso? E para ser claro, estamos falando de primeira classe aqui.
java
pointers
delegates
function-pointers
dreadwail
fonte
fonte
this::myMethod
é semanticamente o mesmo que criar um lambdaparamA, paramB -> this.myMethod(paramA, paramB)
.Respostas:
O idioma Java para a funcionalidade de ponteiro de função é uma classe anônima que implementa uma interface, por exemplo
Atualização: o acima é necessário nas versões Java anteriores ao Java 8. Agora temos alternativas muito melhores, ou seja, lambdas:
e referências de método:
fonte
std::bind
, que liga parâmetros a funções e retorna um objeto que pode ser chamado. Não posso defender C por esse motivo, mas C ++ é realmente melhor que Java para isso.Você pode substituir um ponteiro de função por uma interface. Digamos que você deseja executar uma coleção e fazer algo com cada elemento.
Essa é a interface que poderíamos passar para alguns, como CollectionUtils2.doFunc (Coleção c, IFunction f).
Como exemplo, digamos que temos uma coleção de números e você gostaria de adicionar 1 a cada elemento.
fonte
Você pode usar a reflexão para fazer isso.
Passe como parâmetro o objeto e o nome do método (como uma sequência) e, em seguida, chame o método. Por exemplo:
E depois use-o como em:
Obviamente, verifique todas as exceções e adicione os lançamentos necessários.
fonte
Não, funções não são objetos de primeira classe em java. Você pode fazer o mesmo implementando uma classe de manipulador - é assim que os retornos de chamada são implementados no Swing etc.
No entanto, existem propostas de fechamento (o nome oficial do que você está falando) em versões futuras do java - o Javaworld tem um artigo interessante.
fonte
Isso lembra a Execução de Steve Yegge no Reino dos Substantivos . Ele basicamente afirma que Java precisa de um objeto para cada ação e, portanto, não possui entidades "somente verbais", como ponteiros de função.
fonte
Para obter funcionalidade semelhante, você pode usar classes internas anônimas.
Se você definir uma interface
Foo
:Crie um método
bar
que receberá um 'ponteiro de função' como argumento:Por fim, chame o método da seguinte maneira:
fonte
O Java8 introduziu lambdas e referências de método . Portanto, se sua função corresponder a uma interface funcional (você pode criar sua própria), poderá usar uma referência de método neste caso.
Java fornece um conjunto de interfaces funcionais comuns . considerando que você pode fazer o seguinte:
fonte
alias
: por exemplopublic List<T> collect(T t) = Collections::collect
Não existe tal coisa em Java. Você precisará agrupar sua função em algum objeto e passar a referência a esse objeto para passar a referência ao método nesse objeto.
Sintaticamente, isso pode ser facilitado até certo ponto, usando classes anônimas definidas no local ou classes anônimas definidas como variáveis de membro da classe.
Exemplo:
fonte
Implementei o retorno de chamada / delegar suporte em Java usando reflexão. Detalhes e fonte de trabalho estão disponíveis no meu site .
Como funciona
Temos uma classe de princípio chamada Callback com uma classe aninhada chamada WithParms. A API que precisa do retorno de chamada terá um objeto de retorno de chamada como parâmetro e, se necessário, criará um Callback.WithParms como uma variável de método. Como muitas das aplicações desse objeto serão recursivas, isso funciona muito bem.
Com o desempenho ainda sendo uma alta prioridade para mim, eu não queria ser obrigado a criar uma matriz de objetos descartáveis para armazenar os parâmetros de cada chamada - afinal, em uma grande estrutura de dados, poderia haver milhares de elementos e no processamento de mensagens Nesse cenário, poderíamos acabar processando milhares de estruturas de dados por segundo.
Para ser thread-safe, a matriz de parâmetros precisa existir exclusivamente para cada chamada do método API e, para eficiência, o mesmo deve ser usado para cada chamada do retorno de chamada; Eu precisava de um segundo objeto que seria barato criar para vincular o retorno de chamada a uma matriz de parâmetros para invocação. Mas, em alguns cenários, o invocador já teria uma matriz de parâmetros por outros motivos. Por esses dois motivos, a matriz de parâmetros não pertence ao objeto de retorno de chamada. Além disso, a escolha da chamada (passar os parâmetros como uma matriz ou como objetos individuais) pertence às mãos da API usando o retorno de chamada, permitindo que ela use a chamada que melhor se adequar ao seu funcionamento interno.
A classe aninhada WithParms, portanto, é opcional e serve para dois propósitos, contém a matriz de objetos de parâmetro necessária para as chamadas de retorno de chamada e fornece 10 métodos invoke () sobrecarregados (com de 1 a 10 parâmetros) que carregam a matriz de parâmetros e, em seguida, invocar o destino de retorno de chamada.
fonte
Verifique os fechamentos como eles foram implementados na biblioteca lambdaj. Eles realmente têm um comportamento muito semelhante aos delegados em C #:
http://code.google.com/p/lambdaj/wiki/Closures
fonte
Em relação à maioria das pessoas aqui, sou novo no java, mas como não vi uma sugestão semelhante, tenho outra alternativa a sugerir. Não tenho certeza se é uma boa prática ou não, ou mesmo sugerida antes e eu simplesmente não entendi. Eu gosto desde que eu acho que é auto-descritivo.
dependendo da aplicação, atribua
etc.
e ligue por
fonte