成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java generic中通配符的幾點理解

開發 后端
結合Java本身的一些面向對象的特性,我們很容易理解這么一個置換原則。但是在泛型的編程中,我們考慮到子類型關系的時候,更是容易把一種關系給弄混淆,并錯誤的采用置換原則。

置換原則

結合Java本身的一些面向對象的特性,我們很容易理解這么一個置換原則:

一個指定類型的變量可以被賦值為該類型的任何子類;一個指定某種類型參數的方法可以通過傳入該類型的子類來進行調用。

總的來說,就是說我們使用的任何類型變量都可以用該類型的子類型來替換。

泛型中一種錯誤的繼承關系

在泛型的編程中,我們考慮到子類型關系的時候,容易把一種關系給弄混淆,并錯誤的采用置換原則。

比如說:

  1. List<Integer> ints = new ArrayList<Integer>();  
  2. ints.add(1);  
  3. ints.add(2);  
  4. List<Number> nums = ints; // compile error 

在這段代碼中,我們看到類型參數Integer是Number的子類型,就容易想當然的認為List<Integer>也是List<Number>的子類。實際上并不是。所以才會導致類型不匹配,產生編譯時錯誤。

有點時候,我們覺得,這樣的轉換看似不能用到一個好處,就是利用對象之間繼承的關系。要是我們能有一個列表,它既能處理某種類型的數據,還能處理該類型的所有子類型的數據,這樣豈不是既能用到泛型的好處又可以用到對象關系的好處么?于是在這里就引出了通配符(wildcard)。

通配符(Wildcard)

在Java類庫中Collection接口定義中有一個用到通配符的方法:

  1. interface Collection<E> {  
  2. ...  
  3. public boolean addAll(Collection<? extends E> c);  
  4. ...  

在addAll方法的描述里,可以接受Collection類型的參數。其中Collection中的類型參數可以為任何繼承E的子類型。

因此,我們可以在實際代碼中這么使用:

  1. List<Number> nums = new ArrayList<Number>();  
  2. List<Integer> ints = Arrays.asList(12);  
  3. List<Double> dbls = Arrays.asList(2.783.14);  
  4. nums.addAll(ints);  
  5. nums.addAll(dbls); 

在代碼中我們可以看到,List<Integer>和List<Double>都是Collection<? extends Number>類型的子類。所以上面的方法中可以將Integer和Double兩種類型的List傳入到方法中。

通配符使用限制1:

使用通配符的泛型數據類型比較有意思,既然前面我們可以將其作為方法聲明的參數,那么是否可以將它作為一個變量類型來直接創建變量呢?

看如下代碼:

  1. List<? extends Number> nums = new ArrayList<Integer>(); //compile error 

實際上上面這段代碼是編譯通不過的。

通配符使用限制2:

既然不能用來直接創建變量對象,那么再看下面這段代碼:

  1. List<Integer> ints = new ArrayList<Integer>();  
  2. ints.add(1);  
  3. ints.add(2);  
  4. List<? extends Number> nums = ints;  
  5. nums.add(3.14); // compile error 

這段代碼的第5行會導致編譯錯誤。在第4行代碼中,我們將ints賦值給nums,表面上nums聲明為一個List<Integer>的父類型,所以第4行編譯正常。為什么第5行代碼會出錯呢?表面上看來,既然nums類型可以接受繼承自Number的所有參數,那加一個Double類型的數據應該是沒問題的。實際上我們再考慮一下這樣會帶來的問題:

nums本來引用的是一個繼承自該類型的List<Integer>,如果我們允許加入Double類型的數據的話,那么ints這個Integer的List里面就包含了Double的數據,當我們使用ints的時候,和我們所期望的只包含Integer類型的數據不符合。

 

因此,這段代碼也說明了一個問題,就是在? extends E這種通配符引用的數據類型中,如果向其中增加數據操作的話會有問題。所以向其中增加數據是不允許的。但是我們可以從其中來讀取數據。

總結:

1:通配符修飾的泛型不能用來直接創建變量對象。

2:通配符修飾相當于聲明了一種變量,它可以作為參數在方法中傳遞。這么做帶來的好處就是我們可以將應用于包含某些數據類型的列表的方法也應用到包含其子類型的列表中。相當于可以在列表中用到一些面向對象的特性。

原文鏈接:http://shmilyaw-hotmail-com.iteye.com/blog/1405904

【編輯推薦】

  1. Java中泛型創建數組的總結
  2. Java Socket超時淺析
  3. Java Socket重要參數講解
  4. 對于Java類加載過程中的順序問題探究
  5. 深入理解Java對象序列化
責任編輯:林師授 來源: frank-liu的博客
相關推薦

2012-03-21 10:30:58

Java

2023-03-04 21:05:53

JAVA泛型通配符

2009-06-22 13:46:00

java程序員考試

2015-11-02 17:20:00

Java弱引用

2009-07-20 15:39:32

ASP.NET緩存

2011-09-28 11:14:35

Zshellzshbash shell

2018-07-09 15:11:14

Java逃逸JVM

2021-02-25 10:20:26

Java接口代碼

2010-12-07 11:22:02

提薪

2009-04-10 09:43:00

Java輸出流異常

2017-09-23 15:28:32

JavaOptional方法

2010-06-01 13:32:15

Visual Stud

2014-11-11 15:25:30

PHPWeb

2009-06-29 18:26:46

HibernateHQL查詢

2009-03-17 16:22:13

Java泛型接口

2012-03-07 09:02:29

代碼復用

2018-03-07 12:50:59

Apache優化建議

2021-06-18 08:25:42

Java泛型通配符

2009-08-13 09:01:00

ASP.NET開發Web標準

2020-08-23 11:32:21

JavaScript開發技術
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 午夜寂寞影院列表 | 国产一区二区免费 | 日韩中文在线 | 黄色国产视频 | 一区二区视频在线观看 | 天堂资源最新在线 | 久久久精品综合 | 中文字幕日韩欧美一区二区三区 | 国产精品视频97 | 国产精品爱久久久久久久 | 免费a v网站 | 91精品一区 | 午夜免费成人 | www.99精品| 亚洲一区二区久久久 | 国产精品欧美一区二区三区 | 成人毛片网站 | 91精品一区二区三区久久久久久 | 国产精品亚洲一区二区三区在线 | 久久精品国产一区二区电影 | 日韩二三区 | 免费一区 | 久久极品 | 久久免费国产 | 人人干天天干 | 在线视频日韩 | 欧美二区乱c黑人 | 日本精品在线一区 | 日韩一级免费观看 | 国产高清在线观看 | 国产成人aⅴ | 中文字幕国产一区 | 91一区二区三区在线观看 | 午夜天堂 | 午夜影院视频 | 久久精品国产免费 | 国产精品免费一区二区三区四区 | 在线看亚洲| 精品1区2区 | 中文字幕在线一区 | 精品美女 |