Home > Software design >  Since String is a final class, how can a wildcard <? extends String> be correct?
Since String is a final class, how can a wildcard <? extends String> be correct?

Time:06-10

In a course on Spring Batch, I was surprised to see ? extends String. Since String is a final class, how is this correct?

            public void write(List<? extends String> items) throws Exception {
                System.out.println(String.format("Received list of size: %s", items.size()));
                items.forEach(System.out::println);
            }

CodePudding user response:

Technically you are correct, in this case only a String would work because String is final. Still best to always follow PECS. A more practical example would probably use ? extends CharSequence. For example,

public static void write(List<? extends CharSequence> items) {
    System.out.println(String.format("Received list of size: %s", items.size()));
    items.forEach(System.out::println);
}

Now you can call it with any kind of CharSequence.

public static void main(String[] args) {
    write(List.of(new StringBuilder("Hello"), new StringBuilder("World")));
    write(List.of("Hello", "World"));
}

CodePudding user response:

You're correct that there will never be another class that extends String. So the only type that can fill that ? is String itself. However, the extends / super still conveys intent. Namely, a List<? extends String> is a read-only list. You can't add elements to it since ? extends String is a producer. A List<String> is potentially a read-write collection. So by writing List<? extends String>, we're conveying to whoever is reading the code (and to the compiler) that we only intend to read values from this List, not write anything back.

CodePudding user response:

? extends String is a generics qualifier. What it means in this particular case is that the method expects a List of elements which are compatible with String. There is nothing wrong with this definition - in fact, I would even consider it slightly more accurate and universal than List<String>.

But you're right, since there will never be another String, this is equivalent to List<String> for all practical purposes.

  •  Tags:  
  • java
  • Related