Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

174
Views
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 answers
Answer question

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!