學習使用泛型編程時更困惑的一個方面是肯定什麼時候使用上界通配符以及什麼時候使用下界通配符,此頁面提供了設計代碼時要遵循的一些準則。程序員
對於本文的討論,將變量看做提供的兩個功能之一是有幫助的:編程
「in」變量向代碼提供數據,想象一下帶有兩個參數的複製方法:copy(src, dest)
,src
參數提供要複製的數據,所以它是「in」參數。segmentfault
「out」變量保存數據以供其餘地方使用,在複製示例中,copy(src, dest)
,dest
參數接受數據,所以它是「out」參數。學習
固然,一些變量既用於「in」又用於「out」目的 — 該場景也在指南中解決。this
在決定是否使用通配符以及適合使用哪一種類型的通配符時,能夠使用「in」和「out」原則,如下列表提供了遵循的準則:設計
extends
關鍵字定義帶有上界通配符的「in」變量。super
關鍵字定義帶有下界通配符的「out」變量。Object
類中定義的方法訪問「in」變量的狀況下,使用無界通配符。這些指南不適用於方法的返回類型,應該避免使用通配符做爲返回類型,由於它強制程序員使用代碼來處理通配符。code
由List<? extends ...>
定義的列表能夠非正式地認爲是隻讀的,但這不是一個嚴格的保證,假設你有如下兩個類:rem
class NaturalNumber { private int i; public NaturalNumber(int i) { this.i = i; } // ... } class EvenNumber extends NaturalNumber { public EvenNumber(int i) { super(i); } // ... }
考慮如下代碼:get
List<EvenNumber> le = new ArrayList<>(); List<? extends NaturalNumber> ln = le; ln.add(new NaturalNumber(35)); // compile-time error
由於List<EvenNumber>
是List<? extends NaturalNumber>
的子類型,你能夠將le
賦給ln
,可是你不能使用ln
將天然數添加到偶數列表中,如下列表中的操做是可能的:class
null
。clear
。remove
。你能夠看到List<? extends NaturalNumber>
定義的列表在嚴格意義上不是隻讀的,但你可能會這樣想,由於你沒法存儲新元素或更改列表中的現有元素。