? extends E and ? super E

? extends E and ? super E

B类:
public class B implements C {
@Override
public Map convert(Object from) {
return null;
}

}

C类:
@FunctionalInterface
public interface C<F, T, D> {

Map<String, Integer> convert(T from);

}

W类:
public class W extends V {

}


V类:
public class V implements D {

public void f() {
}
}

D interface: (the implementation class that implements the interface can call the method of the interface -> ? D in extends D can be a class or an interface, it does not affect)
public interface D {

}


Z类:
public class Z extends W {

}

A类:
public class A {
public void f() {

B b = new B();

C c = new B();

Vv = new V();

D d = new D();

W w = new W();

Z z = new Z ();

Map<String, ? extends C> map = new HashMap<>();
map.put("", b); //The compilation fails! -> Because I don't know the specific implementation class

Map<String, ? super C> map2 = new HashMap<>();
map2.put("", b); //Compilation passed! ->Because the lower limit of put() is C, and class B implements the C interface;

Map<String, ? super V> map3 = new HashMap<>();
map3.put("", d); //The compilation fails! -> because d is not a subclass of V

Map<String, ? super V> map4 = new HashMap<>();
map3.put("", w); //Compilation passed! ->Because w is a subclass of V
map3.put("", v); //Compilation passed! -> What is added is V's own
map3.put("", z); //The compilation is passed! ->Because z is a subclass of W, it is also a subclass of V
}
}

 

 

Summary:
  ! ! ! The E here is understood as a scope, not just a class, the scope is (from the parent class to its subclasses).
 
  
  ? extends E: refers to E and its subclasses of E, and specifies the upper limit (E) of generics. Since E is the uppermost class in the range, it is not allowed in list.add (concrete class). Because only the upper limit of generics is known, but the object added specifically does not necessarily match the class in list = new ArrayList<>(), there will be a type conversion problem, so it cannot be added at all.

? super E: refers to E and its parent class of E, and specifies the lower limit of generics (E). Since the lower limit of generics E is specified, the added object can only be a subclass of E or E, so that no There will be a type conversion error, which can be added and the compilation succeeds.

 

eg: Explain with list, map is the same


There are currently four classes, Person class, Student class, Teacher class, GoodStudent class.

The relationship between the four classes: The
Student class and the Teacher class both inherit the Person class and the
GoodStudent class inherits from the Student class

? extends Person class: At this time, the specified upper limit is Person. When list.add(), since only the upper limit is known to be Person, I do not know what type of list is ( List<> list = new ArrayList<>(); ) , so it cannot be added, because when new ArrayList<>, the <> generic type may be Teacher or Student, so no matter what list.add() is at this time, it will not compile. -->Because no specific ArrayList<> has been specified at this time;

? super Student : The lower limit specified at this time is Student. In list.add(), only addStudent or its subclasses can be added. This is already specified, so at this time, we can add (Student/Student subclasses) ).

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324769160&siteId=291194637