Este é um pequeno trecho de código retirado de alguns dos exemplos que acompanham o Stanford Parser. Estou desenvolvendo em Java há cerca de 4 anos, mas nunca tive uma compreensão muito forte do que esse estilo de código deveria indicar.
List<? extends HasWord> wordList = toke.tokenize();
Não estou preocupado com os detalhes do código. O que me deixa confuso é o que exatamente a expressão genérica deve transmitir, em inglês.
Alguém pode me explicar isso?
Respostas:
significa "Uma classe / interface que se estende
HasWord
". Em outras palavras,HasWord
ele próprio ou qualquer um de seus filhos ... basicamente qualquer coisa que funcione cominstanceof HasWord
maisnull
.Em termos mais técnicos,
? extends HasWord
é um curinga limitado, coberto no Item 31 do Effective Java 3rd Edition , a partir da página 139. O mesmo capítulo da 2ª Edição está disponível online como PDF ; a parte dos curingas delimitados é o Item 28, começando na página 134.Atualização: o link do PDF foi atualizado desde que a Oracle o removeu há um tempo. Agora ele aponta para a cópia apresentada pela Escola de Engenharia Eletrônica e Ciência da Computação da Universidade Queen Mary de Londres.
Atualização 2: Vamos detalhar um pouco mais o motivo pelo qual você deseja usar caracteres curinga.
Se você declarar um método cuja assinatura espera que você passe
List<HasWord>
, a única coisa que você pode passar é aList<HasWord>
.No entanto, se a assinatura for essa
List<? extends HasWord>
, você poderá passar umaList<ChildOfHasWord>
.Observe que há uma diferença sutil entre
List<? extends HasWord>
eList<? super HasWord>
. Como Joshua Bloch colocou: PECS = produtor-estende, consumidor-super.O que isso significa é que, se você estiver passando uma coleção da qual seu método extrai dados (ou seja, a coleção está produzindo elementos para o seu método), você deve usá-la
extends
. Se você estiver passando uma coleção à qual seu método adiciona dados (ou seja, a coleção está consumindo elementos criados por seu método), ela deve ser usadasuper
.Isso pode parecer confuso. No entanto, você pode vê-lo no comando
List
'ssort
(que é apenas um atalho para a versão de dois argumentos do Collections.sort). Em vez de pegar umComparator<T>
, ele realmente leva umComparator<? super T>
. Nesse caso, o comparador está consumindo os elementos do aList
fim de reordenar a própria lista.fonte
List<HasWord>
é exatamente o que você descreve: uma lista que contém objetosx
para os quaisx instanceof HasWord
retorna true enull
. Você não precisa de um curinga para isso. O curinga significa que na verdade também pode ser uma lista de outro tipo, desde que esse tipo seja um subtipo deHasWord
. (Desculpe tarde comentário.)Um ponto de interrogação é um significante para 'qualquer tipo'.
?
sozinho significaenquanto o seu exemplo acima significa
fonte
public Set<Class<?>> getClasses()
significa? Qual a diferençaSet<Class>
? Eu estou olhandojavax.ws.rs.core.Application
.List<? extends HasWord>
aceita quaisquer classes concretas que estendem o HasWord. Se você tem as seguintes classes ...... o
wordList
SOMENTE pode conter uma lista de As ou Bs ou mistura de ambos, porque ambas as classes estendem o mesmo pai ounull
(o que falha na verificação de instânciaHasWorld
).fonte
List<? extends Collection<String>> list = new ArrayList<List<String>>();
.List<HasWord>
faz o mesmo para isso. O ponto aqui é que essa variável pode conter umList<A>
ouList<B>
tão bem como umList<HasWord>
.Talvez um exemplo artificial do "mundo real" ajudasse.
No meu local de trabalho, temos caixotes do lixo com sabores diferentes. Todas as caixas contêm lixo, mas algumas são especializadas e não levam todos os tipos de lixo. Então nós temos
Bin<CupRubbish>
eBin<RecylcableRubbish>
. O sistema de tipos precisa ter certeza de que não posso colocar o meuHalfEatenSandwichRubbish
em nenhum desses tipos, mas ele pode entrar em uma lixeira geralBin<Rubbish>
. Se eu quisesse falar sobre umBin
dosRubbish
quais pode ser especializado para não colocar lixo incompatível, então seriaBin<? extends Rubbish>
.(Nota:
? extends
não significa somente leitura. Por exemplo, posso, com as devidas precauções, retirar um pedaço de lixo de uma lixeira de especialidade desconhecida e depois colocá-lo novamente em um local diferente.)Não tenho certeza de quanto isso ajuda. Ponteiro para ponteiro na presença de polimorfismo não é totalmente óbvio.
fonte
Em inglês:
Em geral, os
?
genéricos in significam qualquer classe. Eextends SomeClass
especifica que esse objeto deve se estenderSomeClass
(ou ser essa classe).fonte
O ponto de interrogação é usado para definir caracteres curinga . Confira a documentação do Oracle sobre eles: http://docs.oracle.com/javase/tutorial/java/generics/wildcards.html
fonte