0
package test16;

import java.util.ArrayList;
import java.util.List;

class A {
}

class B extends A {
}

public class Test1 {
    public static void main(String[] args) {
        List list1 = new ArrayList();
        List<A> list2 = new ArrayList<A>();
        List<A> list3 = new ArrayList<>();
        List<A> list4 = new ArrayList<B>();

        List<? extends A> list101 = new ArrayList<A>();
        List<? extends A> list102 = new ArrayList<B>();

        List<? extends A> list5 = new ArrayList<>();
        A getA = list5.get(0);// return A
        list5.add(new A());// error
        list5.add(new B());// error
    }
}

? extends : all add() error.

package test17;

import java.util.ArrayList;
import java.util.List;

class A {
}

class B extends A {
}

public class Test1 {
    public static void main(String[] args) {
        List list1 = new ArrayList();
        List<B> list2 = new ArrayList<B>();
        List<B> list3 = new ArrayList<>();
        List<B> list4 = new ArrayList<A>();

        List<? super B> list101 = new ArrayList<A>();
        List<? super B> list102 = new ArrayList<B>();

        List<? super B> list5 = new ArrayList<>();
        Object object = list5.get(0);//return Object
        list5.add(new A());// error
        list5.add(new B());// ok
    }
}

? super : add() run ok .


I want to know what kind of considerations the generic designer is, extends can't be added at all, and super can be added

but stackoverflow not find it answer.

thank you very much!

startjava
  • 33
  • 5

2 Answers2

2

The extends wildcards in Java Generics.

private static double sum(Collection<? extends Number> numbers) {
double result = 0.0;

for (Number num : numbers) result += num.doubleValue();

return result;
}

The above method has the wildcard has the notion of <? extends Number>. the compiler will allow to pass a collection of a subtype of Number. However you cannot add elements to the collection declared with the extends wildcard.

List<? extends Number> numbers = new ArrayList<Integer>();
numbers.add(123); // COMPILE ERROR 

Otherwise, we could add a double number to a collection which is designed to accept only integer numbers.

The super wildcard in Java generics.

public static void append(Collection<? super Integer> integers, int n) {
for (int i = 1; i <= n; i++) {
    integers.add(i);
}
}

In the above method you can restrict the elements being added in the method is of type Integer, whereas we also want to accept a collection of super types of Integer, since adding integers to a collection of numbers is perfectly legal.

List<Number> numbers = new ArrayList<Number>();
append(numbers, 5);
numbers.add(6.789);

System.out.println(numbers);

Ideas behind the super wildcard: ( type declared with a wildcard <? super T>)

  1. It can accept any type that is super type of T
  2. We can add elements to the collection. However the type is restricted to only T
  3. It cannot be passed to a method having a parameter declared with the extends wildcard.

Generics with extends and super

Thanigai Arasu
  • 413
  • 3
  • 14
  • Thanks Thanigai Arasu, but that's not the answer I want. I want to know why it was designed in the first place, not the result of the code execution. – startjava Mar 06 '20 at 12:04
1
List<? extends A> list5 = new ArrayList<>();
A getA = list5.get(0);// return A
list5.add(new A());// error
list5.add(new B());// error

You are getting errors here because the ? wildcard creates a dynamic type at compile time for you that extends A. A and B are not of the created type so add cannot be used with them.


List<? super B> list5 = new ArrayList<>();
Object object = list5.get(0);//return Object
list5.add(new A());// error
list5.add(new B());// ok

Here is a dynamic type created for you at compile time again. A is not of that created type. B can be used here because it can be casted to the newly created type.


The reason it was designed like that is because it's not meant for the purposes you expect it to be for. When you want to add different types to a collection, use object oriented programming, i.e. inheritance and polymorphism. Generics are for slightly other purposes.

akuzminykh
  • 4,522
  • 4
  • 15
  • 36