List<? extends Father> list = new LinkedList<Son>(); list.add(new Son());Even if you specify the Son type, you cannot add a Son object using the add method. Why can't the Father class and the subclasses of the Father class be added to the list? Let's analyze it. List3f622c4eabd1145a5b9f71573034350b means that the upper limit is Father, and the following assignments are legal
List<? extends Father> list1 = new ArrayList<Father>(); List<? extends Father> list2 = new ArrayList<Son>(); List<? extends Father> list3 = new ArrayList<LeiFeng>();If List3f622c4eabd1145a5b9f71573034350b supports the add method: list1 can add Father and all subclasses of Father;
list1.add(new Father());//error list1.add(new Son());//errorThe reason is that the compiler only knows that the container is Father or its derived class, but it does not know the specific type. . Maybe Father? Maybe Son? Maybe LeiFeng, XiaoMing? After the compiler sees that Father is used for assignment later, the parameter type in the collection is not limited to "Father". Instead, it is marked with a placeholder: CAP#1 to indicate capturing a Father or a subclass of Father. I don’t know the specific class, but the code is CAP#1. Then whether you want to insert Son, LeiFeng or Father compiler, you don't know whether it can match this CAP#1, so you won't allow it. So the difference between wildcard 6b3d0130bba23ae47fe2b8e8cddf0195 and type parameters is that to the compiler, all T represents the same type. For example, in the following generic method, the three T's all refer to the same type, either String or Integer.
public <T> List<T> fill(T... t);But the wildcard 6b3d0130bba23ae47fe2b8e8cddf0195 does not have such a constraint. List6b3d0130bba23ae47fe2b8e8cddf0195 simply means: there is something in the collection, and I don’t know what it is. So the error here is that nothing can be put in List3f622c4eabd1145a5b9f71573034350b. List3f622c4eabd1145a5b9f71573034350b list cannot be added, but this form is still very useful. Although the add method cannot be used, a Season can specify different types during initialization. For example:
List<? extends Father> list1 = getFatherList();//getFatherList方法会返回一个Father的子类的listIn addition, since we have ensured that the Father class or one of its subclasses is stored in the List, you can use the get method to directly obtain the value:
List<? extends Father> list1 = new ArrayList<>(); Father father = list1.get(0);//读取出来的东西只能存放在Father或它的基类里。 Object object = list1.get(0);//读取出来的东西只能存放在Father或它的基类里。 Human human = list1.get(0);//读取出来的东西只能存放在Father或它的基类里。 Son son = (Son)list1.get(0);Lower bound< ;? super T> does not affect storage in, but retrieval can only be placed in the Object object. The lower bound is declared with super, indicating that the parameterized type may be the specified type, or this type Parent type, up to Object.
//super只能添加Father和Father的子类,不能添加Father的父类,读取出来的东西只能存放在Object类里 List<? super Father> list = new ArrayList<>(); list.add(new Father()); list.add(new Human());//compile error list.add(new Son()); Father person1 = list.get(0);//compile error Son son = list.get(0);//compile error Object object1 = list.get(0);
The above is the detailed content of What are extends T and super T in Java?. For more information, please follow other related articles on the PHP Chinese website!