亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

java范型

2019-11-06 06:26:38
字體:
來源:轉載
供稿:網友

這里寫圖片描述

java泛型由來的動機

理解Java泛型最簡單的方法是把它看成一種便捷語法,能節省你某些Java類型轉換(casting)上的操作;以及防止代碼運行時出現ClassCastException。

泛型的構成

范型類、范型接口public interface List<T> extends Collection<T> { //get方法實際返回的是一個類型為T的對象,T是在List<T>聲明中的類型變量。 T get(int index); <T1> void put(T1 t); Iterator<E> iterator();...}泛型方法和構造器(Constructor)//如果方法和構造器上聲明了一個或多個類型變量,它們也可以泛型化//使用場景:靜態、final、工具類public final class Collections2 { public static <E> Collection<E> filter(Collection<E> unfiltered, PRedicate<? super E> predicate) { ... }}

遍歷使用

類庫中的很多類,諸如Iterator,功能都有所增強,被泛型化。List接口里的iterator()方法現在返回的是Iterator,由它的T next()方法返回的對象不需要再進行類型轉換,你直接得到正確的類型。使用foreach,“for each”語法同樣受益于泛型。for (Iterator<String> iter = str.iterator(); iter.hasNext();) {String s = iter.next();System.out.print(s);}for (String s: str) {System.out.print(s);}

自動封裝(Autoboxing)和自動拆封(Autounboxing)

在使用Java泛型時,autoboxing/autounboxing這兩個特征會被自動的用到,就像下面的這段代碼:List<Integer> ints = new ArrayList<Integer>();ints.add(0);ints.add(1);int sum = 0;for (int i : ints) {sum += i;}要明白的一點是,封裝和解封會帶來性能上的損失

通配符

“Producer Extends” – 如果你需要一個只讀List,用它來produce T,那么使用? extends T?!癈onsumer Super” – 如果你需要一個只寫List,用它來consume T,那么使用? super T。

如果需要同時讀取以及寫入,那么我們就不能使用通配符了。

如何閱讀過一些Java集合類的源碼,可以發現通常我們會將兩者結合起來一起用,比如像下面這樣:

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)); }}

類型擦除

  - Java泛型中最令人苦惱的地方或許就是類型擦除了,特別是對于有C++經驗的程序員。類型擦除就是說Java泛型只能用于在編譯期間的靜態類型檢查,然后編譯器生成的代碼會擦除相應的類型信息,這樣到了運行期間實際上JVM根本就知道泛型所代表的具體類型。這樣做的目的是因為Java泛型是1.5之后才被引入的,為了保持向下的兼容性,所以只能做類型擦除來兼容以前的非泛型代碼。對于這一點,如果閱讀Java集合框架的源碼,可以發現有些類其實并不支持泛型。

public class Generic { static List<Apple> apples = Arrays.asList(new Apple()); static List<Fruit> fruit = Arrays.asList(new Fruit()); static class Reader<T> { T readExact(List<T> list) { return list.get(0); } } static void f1() { Reader<Fruit> fruitReader = new Reader<Fruit>(); // Errors: List<Fruit> cannot be applied to List<Apple>. // Fruit f = fruitReader.readExact(apples); } //但是按照我們通常的思維習慣,Apple和Fruit之間肯定是存在聯系,然而編譯器卻無法識別, // 那怎么在泛型代碼中解決這個問題呢?我們可以通過使用通配符來解決這個問題: static class CovariantReader<T> { T readCovariant(List<? extends T> list) { return list.get(0); } } static void f2() { CovariantReader<Fruit> fruitReader = new CovariantReader<Fruit>(); Fruit f = fruitReader.readCovariant(fruit); Fruit a = fruitReader.readCovariant(apples); } static void add() { // Wildcards allow covariance: List<? extends Fruit> flist = new ArrayList<Apple>(); // Compile Error: can't add any type of object: // flist.add(new Apple()) // flist.add(new Orange()) // flist.add(new Fruit()) // flist.add(new Object()) flist.add(null); // Legal but uninteresting // We Know that it returns at least Fruit: Fruit f = flist.get(0); //答案是否定,Java編譯器不允許我們這樣做,為什么呢? // 對于這個問題我們不妨從編譯器的角度去考慮。因為List<? extends Fruit> flist它自身可以有多種含義:// List<? extends Fruit> flist = new ArrayList<Fruit>();// List<? extends Fruit> flist = new ArrayList<Apple>();// List<? extends Fruit> flist = new ArrayList<Orange>(); } public static void main(String[] args) { f1(); f2(); } static class Fruit { } static class Apple extends Fruit { } static class Orange extends Fruit { }}4種案例public class Test2 { public static void quetion1() { //問題一:在Java中不允許創建泛型數組,類似下面這樣的做法編譯器會報錯: List<Integer>[] arrayOfLists = new List<Integer>[2]; // compile-time error //對于下面這段代碼還是很好理解,字符串數組不能存放整型元素, //而且這樣的錯誤往往要等到代碼運行的時候才能發現,編譯器是無法識別的。 Object[] strings = new String[2]; strings[0] = "hi"; // OK strings[1] = 100; // An ArrayStoreException is thrown. //由于運行時期類型信息已經被擦除,JVM實際上根本就不知道new ArrayList<String>()和new ArrayList<Integer>()的區別 Class c1 = new ArrayList<String>().getClass(); Class c2 = new ArrayList<Integer>().getClass(); System.out.println(c1.getName() + c2.getName() + (c1 == c2)); // true } //問題二(還沒理解,參看尾部的參考):繼續復用我們上面的Node的類,對于泛型代碼,Java編譯器實際上還會偷偷幫我們實現一個Bridge method。? public static void question2() { //最佳實踐,建設類型推斷,顯示設置返回類型。 } // 問題三:正如我們上面提到的,Java泛型很大程度上只能提供靜態類型檢查, // 然后類型的信息就會被擦除,所以像下面這樣利用類型參數創建實例的做法編譯器不會通過: public static <E> void append(List<E> list) { E elem = new E(); // compile-time error list.add(elem); } //但是如果某些場景我們想要需要利用類型參數創建實例,我們應該怎么做呢?可以利用反射解決這個問題: public static <E> void append(List<E> list, Class<E> cls) throws Exception { E elem = cls.newInstance(); // OK list.add(elem);// List<String> ls = new ArrayList();// append(ls, String.class); } //問題四:我們無法對泛型代碼直接使用instanceof關鍵字, //因為Java編譯器在生成代碼的時候會擦除所有相關泛型的類型信息, //正如我們上面驗證過的JVM在運行時期無法識別出ArrayList<Integer>和ArrayList<String>的之間的區別: public static <E> void rtt(List<E> list) { if (list instanceof ArrayList<Integer>) { // compile-time error // ... } } //和上面一樣,我們可以使用通配符重新設置bounds來解決這個問題: public static void rtti(List<?> list) { if (list instanceof ArrayList<?>) { // OK; instanceof requires a reifiable type // ... } } public class Node<T extends Comparable<T>> { private T data; private Node<T> next; public Node(T data, Node<T> next) { this.data = data; this.next = next; } public T getData() { return data; } // ... }}

Effective Java 范型

不要在新代碼中使用原生態類型:Set< Object >是個參數化類型,可以包含任何對象類型的一個集合;Set< ?>則是一個通配符類型,表示可以包含某種未知對象類型的一個集合;Set 則是一個原生態類型,它脫離類范型系統。前兩者是安全的,后一種不安全。

消除 unchecked cast warnings;unchecked conversion warnings.

列表優先于數組:數組提供了運行時的類型安全,但是沒有編譯時的類型安全。

Java 泛型詳解


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美激情视频在线观看| 91精品久久久久久久久青青| 亚州精品天堂中文字幕| 136fldh精品导航福利| 欧美成人在线影院| 国产精品亚洲欧美导航| 久久男人av资源网站| 亚洲伊人成综合成人网| 久久久人成影片一区二区三区观看| 国内精品久久久久影院 日本资源| 欧美资源在线观看| 亚洲一二三在线| 国产精品免费在线免费| 亚洲全黄一级网站| 国产精品免费看久久久香蕉| 一本色道久久88综合亚洲精品ⅰ| 亚洲国产精品电影在线观看| 午夜精品一区二区三区在线视| 国产精品偷伦免费视频观看的| 亚洲国产成人精品女人久久久| 国产精品久久久久久久久免费| 亚洲一区二区三区乱码aⅴ| 欧美一性一乱一交一视频| 成人性教育视频在线观看| 日韩免费在线电影| 最近中文字幕2019免费| 97久久精品人人澡人人爽缅北| 国产亚洲一级高清| 亚洲一区二区三区四区视频| 精品国产一区二区三区久久久| 姬川优奈aav一区二区| 亚洲成人黄色网| 欧美电影在线观看网站| 精品视频一区在线视频| 亚洲国产日韩精品在线| 性金发美女69hd大尺寸| 美女av一区二区三区| 亚洲免费人成在线视频观看| 亚洲字幕在线观看| 中文字幕日韩欧美精品在线观看| 狠狠久久亚洲欧美专区| 欧美日韩国产一区在线| 精品人伦一区二区三区蜜桃网站| 日韩精品在线观看一区二区| 欧美极品第一页| 亚洲第一区在线| 色妞一区二区三区| 欧美成人久久久| 国产精品福利观看| 国产精品久久久久秋霞鲁丝| 国产精品视频精品| 亚洲欧美中文字幕在线一区| 国产欧美日韩精品专区| 亚洲激情视频在线观看| 欧美国产第二页| 国产精品18久久久久久麻辣| 亚洲欧美一区二区三区情侣bbw| 亚洲免费伊人电影在线观看av| 中文字幕在线精品| 国产91在线播放九色快色| 久久久久女教师免费一区| 欧美日韩中文字幕日韩欧美| 亚洲在线视频观看| 精品毛片三在线观看| 国产午夜精品全部视频播放| 国产精品美女久久久久久免费| 欧美激情亚洲视频| 清纯唯美亚洲激情| 精品国产91久久久久久老师| 久久男人资源视频| 国产精品一香蕉国产线看观看| 欧美激情欧美激情在线五月| 久久久久久久久久久久久久久久久久av| 欧美国产极速在线| 精品国产一区二区三区四区在线观看| 亚洲免费电影在线观看| 欧美综合国产精品久久丁香| 久久精品国产亚洲精品| 日韩在线欧美在线国产在线| 亚洲国产日韩欧美在线动漫| 亚洲欧美日韩天堂| 在线观看视频99| 欧美亚洲国产日韩2020| 成人午夜高潮视频| 国产成人精品免高潮费视频| 欧美黑人性猛交| 国产成人久久久精品一区| 国产精品爽爽爽| 国产在线98福利播放视频| 日韩中文字幕网址| 日韩资源在线观看| 2018中文字幕一区二区三区| www.亚洲人.com| 欧美国产乱视频| 精品亚洲永久免费精品| 久久在线视频在线| 欧美中文字幕在线| 国产精品视频免费在线观看| 国产精品国模在线| 亚洲成年网站在线观看| 精品久久久国产| 日本成人激情视频| 97精品国产97久久久久久免费| 91精品国产综合久久久久久久久| 精品久久久久久中文字幕一区奶水| 欧美日韩免费区域视频在线观看| 欧美天天综合色影久久精品| 欧美在线视频在线播放完整版免费观看| 亚洲福利视频免费观看| 色中色综合影院手机版在线观看| 久久精视频免费在线久久完整在线看| 性欧美xxxx| 国产91精品黑色丝袜高跟鞋| 亚洲精品综合精品自拍| 欧美视频一区二区三区…| 中文字幕av一区| 日韩美女写真福利在线观看| 久久精品男人天堂| 欧美亚洲激情在线| 91色视频在线导航| 456亚洲影院| 清纯唯美亚洲激情| 欧美乱大交xxxxx| 日韩视频亚洲视频| 97不卡在线视频| 欧美一级bbbbb性bbbb喷潮片| 国产一区二区三区在线看| 亚洲天堂网站在线观看视频| 国产在线98福利播放视频| 国产精品自产拍在线观看中文| 国产亚洲精品一区二555| 欧美性视频在线| 国产精品久久久久7777婷婷| 亚洲第一免费播放区| 91成人福利在线| 欧美性视频精品| 久久视频免费在线播放| 欧美视频免费在线观看| 久久在精品线影院精品国产| 欧美色videos| 亚洲国产成人在线播放| 97国产在线视频| 日韩中文视频免费在线观看| 午夜精品视频在线| 69**夜色精品国产69乱| 亚洲天堂色网站| 国产精品久久久久久网站| 中文字幕视频在线免费欧美日韩综合在线看| 欧美激情在线狂野欧美精品| 日本成人免费在线| 这里只有精品在线观看| 亚洲欧美日韩精品久久亚洲区| 97视频在线观看网址| 欧美午夜www高清视频| 欧美猛交ⅹxxx乱大交视频| 亚洲石原莉奈一区二区在线观看| 国产91精品久久久久| 精品国产一区二区在线| 国内精品400部情侣激情| 欧美日韩免费看| 97av在线视频免费播放| 久久久久久久激情视频| 最新中文字幕亚洲| 一区国产精品视频|