zoukankan      html  css  js  c++  java
  • java 学习中遇到的问题(二)泛型中<? extends T>和<? super T>的区别

    对于一个是List<? extends T>类型的引用list1,这实际上是某种list1引用没有指定的具体类型,它是T的一种子类,但到底是哪一种子类,编译器也无法确定,因此无法使用add()来添加对象,但是因为可以确定这个list1中的任何对象至少是T类型的,因此可以用get()来返回一个T类型的对象。

    而对于一个是List<? super T>类型的引用list2,这实际上是T的一种基类,但由于不能确定到底是哪一种基类,因此list2使用get()返回来的只能是一个Object类型,原本的T类型会丢失,不过由于已经知道参数是T的某种基类,所以向其中添加T或T的子类型都是安全的,但若是向其中添加任何T的基类则会由于不确定性而报错(即使添加Object类型也不行)。

     1 import java.util.*;
     2 
     3 public class Demo_twentyeight {
     4     static class Generic1<T>{
     5         private T item;
     6         public void put(T item){
     7             this.item=item;
     8         }
     9     }
    10 
    11     static class Generic2<T>{
    12         T item;
    13         T get(){
    14             return item;
    15         }
    16     }
    17     static <T> void f1(Generic1<? super T> generic1,T item){
    18         generic1.put(item);
    19     }
    20     static <T> void f2(Generic2<? extends T> generic2){
    21         generic2.get();
    22     }
    23     public static void main(String[] args) {
    24         Generic1<Fruit> g1=new Generic1<Fruit>();
    25         g1.put(new Apple());
    26         g1.put(new Fruit());
    27 //        g1.put(new Object());  //编译无法通过
    28         Generic2<Fruit> g2=new Generic2<Fruit>();
    29         Fruit f1=g2.get();
    30     }
    31 
    32 }

    更详细的解答(一位大神写的):http://zhidao.baidu.com/question/646868566975781205.html

  • 相关阅读:
    (22)进程和线程区别
    (21)回调函数
    (20)gevent协程
    (18)ProcessPoolExecutor进程池
    (19)ThreadPoolExecutor线程池
    (17)线程队列---queue LifoQueue PriorityQueue
    (16)线程---定时器Timer
    (15)线程---Condition条件
    (14)线程- Event事件和守护线程Daemon
    IDEA快速搭建WEB项目【记录篇】
  • 原文地址:https://www.cnblogs.com/grj0011/p/4941212.html
Copyright © 2011-2022 走看看