Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

184
Visualizações
Java Generics: What is the benefit of using wildcards here?

The Collections.fill method has the following header:

public static <T> void fill(List<? super T> list, T obj)

Why is the wildcard necessary? The following header seems to work just as well:

public static <T> void fill(List<T> list, T obj)

I cannot see a reason why the wildcard is needed; code such as the following works with the second header as well as the first:

List<Number> nums = new ArrayList<>();
Integer i = 43;
fill(nums, i); //fill method written using second header

My question is: For what specific call of fill would the first header work but not the second? And if there is no such call, why include the wildcard? In this case, the wildcard does not make the method more concise nor add to readability (in my opinion).

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

For your example, the reason it 'works' with your basic <T> signature, is that an Integer is also a Number. The only 'T' that works is T = Number, and then the whole thing just works out.

In this case, the expression you have for the T obj parameter is a reified type: You have an Integer. You could have a T instead. Perhaps you have this:

class AtomicReference<T> {
  // The actual impl of j.u.concurrent.AtomicReference...
  // but with this one additional method:

  public void fillIntoList(List<? super T> list) {
    T currentValue = get();
    Collections.fill(list, currentValue);
  }
}

I may perhaps want to write something like this:

AtomicReference<String> ref = new AtomicReference<String>("hello");
List<CharSequence> texts = new ArrayList<>();

...

ref.fillIntoList(texts);

If my hypothetical fillIntoList method simply had List<T> in the signature that wouldn't compile. Fortunately it does, so the code does compile. Had the Collections.fill method not done the <? super T> thing, the invocation of the Collections.fill method in my fillIntoList method would have failed.

It's highly exotic for any of this to come up. But it can come up. List<? super T> is the strictly superior signature here - it can do everything List<T> does, and more, and it is also semantically correct: Of course I can fill a list-of-foos by writing into every slot a ref to something that I know for sure is a bar, if bar is a child of foo.

over 4 years ago · Santiago Trujillo Relatório

0

That is because the inheritance is useful is some cases.

For example, if you have the following class structure:

public class Parent {
  //some code
}

public class Child extends Parent {
  //some another code
}

You could use the first method writing:

List<Child> children = new ArrayList<>();
Parent otherParentObject = new Parent(); //after this line, set the values for the class
List<Parent> outParentList = new ArrayList<>();
fill(children, otherParentObject); //fill method using first signature;
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda