Producer Extends Consumer Super. Producer Extends, consumer Super.
test
Class inheritance structure: Executive extends Manager extends Employee extends Object
There is also a generic class for testing.
static class Employee {}static class Manager extends Employee {}static class Executive extends Manager {}static class Test<T> {
T value;
public void setValue(T value) {
this.value = value;
}
public T getValue(a) {
returnvalue; }}Copy the code
Can you make sense of the following code
? Extends T initializes
// Test
t4= new Test
(); / / an error
// Test
t5 = new Test
Test<? extends Manager> t6 = new Test<Manager>();
Test<? extends Manager> t7 = new Test<Executive>();
Copy the code
? Super T is initialized
// Test
t1 = new Test
(); / / an error
Test<? super Manager> t2 = new Test<Manager>();
Test<? super Manager> t3 = new Test<Object>();
Test<? super Manager> t4 = new Test<Employee>();
Copy the code
As can be seen,? T and the extend? Super T limits the allowed range of types that can be declared. With Manager as the boundary,? Extend T can declare Manager and below,? Super T can declare Manager and above.
? extends T
Describe an object/container object whose inner object is at least T where all your expectations of T are fulfilled. Can do everything T can do. So we can get(), no matter which subclass of T is in the container or T itself, we can operate as T. This is also known as producer Extends, which provides objects. But you don’t know what T is, what subclass it is. So any of your set operations, or container add operations, are not allowed by Java. Otherwise you might have an apple in a basket of bananas.
Test<? extends Manager> t7 = new Test<Executive>();
// t7.setValue(new Employee()); / / an error
// t7.setValue(new Manager()); / / an error
// t7.setValue(new Executive()); / / an error
// t7.setValue(new Object()); / / an error
Copy the code
Confusing? super T
You might think, by symmetry, right? Super T should describe an object/container that can put anything, as long as it is a parent of T. Include Object. The following statements do not report an error.
Test<? super Manager> t2 = new Test<Manager>();
Test<? super Manager> t3 = new Test<Object>();
Test<? super Manager> t4 = new Test<Employee>();
Copy the code
But you’ll be disappointed to find out. When performing the set operation/container add operation.
Test<? super Manager> t4 = new Test<Employee>();
t4.setValue(new Manager());
t4.setValue(new Executive());
// t4.setValue(new Object()); / / an error
// t4.setValue(new Employee()); / / an error
Copy the code
You can only set/ Add Manager and subclasses of Manager. This is because:? Super T does describe a superclass object/superclass container of T, but you don’t know which one, so you can only set a subclass of T/T. Because all subclasses of T can be converted to any parent class of T. The set/add operation is perfectly safe. This is the consumer super. acceptable object.
Object o = t4.getValue(); Object o = t4.getValue(); It’s legal, but it doesn’t make sense. An Object cannot operate on anything other than a reference.
Container operation
Examples can see awesomehuan.com/2016/03/05/… Deepen the impression.
Clever use
public class Collections {
public static <T> void copy ( List<? super T> dest, List<? extends T> src) {
for (int i=0; i<src.size(); i++) dest.set(i,src.get(i)); }}Copy the code
The copy method in the above code copies data from SRC to DEST, where SRC is the producer and dest is the consumer. The advantage of designing such a method is that it can copy any type of List, which is particularly versatile.
reference
Stackoverflow.com/questions/2…
Awesomehuan.com/2016/03/05/…