泛型類(lèi)型
泛型類(lèi)型是通過(guò)類(lèi)型參數(shù)化的泛型類(lèi)或接口,修改以下Box類(lèi)以演示此概念。
一個(gè)簡(jiǎn)單的Box類(lèi)首先檢查一個(gè)對(duì)任何類(lèi)型的對(duì)象進(jìn)行操作的非泛型Box類(lèi),它只需要提供兩個(gè)方法:set,它將一個(gè)對(duì)象添加到box中,get,它將檢索它:
public class Box { private Object object; public void set(Object object) { this.object = object; } public Object get() { return object; } }
由于它的方法接受或返回一個(gè)Object,所以你可以自由地傳入任何你想要的東西,前提是它不是一種原始類(lèi)型,無(wú)法在編譯時(shí)沒(méi)有辦法驗(yàn)證如何使用該類(lèi),代碼的一部分可能會(huì)在box中放置一個(gè)Integer并期望從中獲取Integer,而代碼的另一部分可能會(huì)錯(cuò)誤地傳入String,從而導(dǎo)致運(yùn)行時(shí)錯(cuò)誤。
Box類(lèi)的泛型版本泛型類(lèi)使用以下格式定義:
class name{ /* ... */ }
由尖括號(hào)(<>)分隔的類(lèi)型參數(shù)部分跟在類(lèi)名后面,它指定類(lèi)型參數(shù)(也稱(chēng)為類(lèi)型變量)T1, T2, ...和Tn。
要更新Box類(lèi)以使用泛型,可以通過(guò)將代碼“public class Box”更改為“public class Box
通過(guò)此更改,Box類(lèi)變?yōu)椋?/p>
/** * Generic version of the Box class. * @paramthe type of the value being boxed */ public class Box { // T stands for "Type" private T t; public void set(T t) { this.t = t; } public T get() { return t; } }
如你所見(jiàn),所有出現(xiàn)的Object都被T替換,類(lèi)型變量可以是你指定的任何非基本類(lèi)型:任何類(lèi)類(lèi)型、任何接口類(lèi)型、任何數(shù)組類(lèi)型,甚至是其他類(lèi)型變量。
可以應(yīng)用相同的技術(shù)來(lái)創(chuàng)建泛型接口。
類(lèi)型參數(shù)命名約定按照慣例,類(lèi)型參數(shù)名稱(chēng)是單個(gè)大寫(xiě)字母,這與你已經(jīng)了解的變量命名約定形成鮮明對(duì)比,并且有充分的理由:如果沒(méi)有這種約定,就很難區(qū)分類(lèi)型變量和普通類(lèi)或接口名稱(chēng)。
最常用的類(lèi)型參數(shù)名稱(chēng)是:
E — 元素(Java集合框架廣泛使用)
K — 鍵
N — 數(shù)
T — 類(lèi)型
V — 值
S、U、V等 — 第二、第三、第四種類(lèi)型
你將在整個(gè)Java SE API和本課程的其余部分中看到這些名稱(chēng)。
調(diào)用和實(shí)例化泛型類(lèi)型要從代碼中引用泛型Box類(lèi),必須執(zhí)行泛型類(lèi)型調(diào)用,它將T替換為某些具體值,例如Integer:
BoxintegerBox;
你可以將泛型類(lèi)型調(diào)用視為與普通方法調(diào)用類(lèi)似,但不是將參數(shù)傳遞給方法,而是將類(lèi)型參數(shù)(在本例中為Integer)傳遞給Box類(lèi)本身。
類(lèi)型參數(shù)和類(lèi)型參數(shù)術(shù)語(yǔ):許多開(kāi)發(fā)人員互換地使用術(shù)語(yǔ)“類(lèi)型參數(shù)”和“類(lèi)型實(shí)參”,但這些術(shù)語(yǔ)并不相同,編碼時(shí),提供類(lèi)型實(shí)參以創(chuàng)建參數(shù)化類(lèi)型,因此,Foo中的T是類(lèi)型參數(shù),而Foo f 中的String是類(lèi)型實(shí)參,本課程在使用這些術(shù)語(yǔ)時(shí)會(huì)遵循此定義。
與任何其他變量聲明一樣,此代碼實(shí)際上并不創(chuàng)建新的Box對(duì)象,它只是聲明integerBox將保存對(duì)“Box of Integer”的引用,這就是Box
泛型類(lèi)型的調(diào)用通常稱(chēng)為參數(shù)化類(lèi)型。
要實(shí)例化此類(lèi),請(qǐng)像往常一樣使用new關(guān)鍵字,但在類(lèi)名和括號(hào)之間放置
Box菱形integerBox = new Box ();
在Java SE 7及更高版本中,只要編譯器可以從上下文中確定或推斷類(lèi)型參數(shù),就可以用一組空的類(lèi)型參數(shù)(<>)替換調(diào)用泛型類(lèi)的構(gòu)造函數(shù)所需的類(lèi)型參數(shù),這對(duì)尖括號(hào)<>非正式地稱(chēng)為菱形,例如,你可以使用以下語(yǔ)句創(chuàng)建Box
BoxintegerBox = new Box<>();
有關(guān)菱形表示法和類(lèi)型推斷的更多信息,請(qǐng)參閱類(lèi)型推斷。
多個(gè)類(lèi)型參數(shù)如前所述,泛型類(lèi)可以有多個(gè)類(lèi)型參數(shù),例如,OrderedPair泛型類(lèi),它實(shí)現(xiàn)了Pair泛型接口:
public interface Pair{ public K getKey(); public V getValue(); } public class OrderedPair implements Pair { private K key; private V value; public OrderedPair(K key, V value) { this.key = key; this.value = value; } public K getKey() { return key; } public V getValue() { return value; } }
以下語(yǔ)句創(chuàng)建OrderedPair類(lèi)的兩個(gè)實(shí)例:
Pairp1 = new OrderedPair ("Even", 8); Pair p2 = new OrderedPair ("hello", "world");
代碼new OrderedPair
正如菱形中所提到的,因?yàn)镴ava編譯器可以從聲明OrderedPair
OrderedPairp1 = new OrderedPair<>("Even", 8); OrderedPair p2 = new OrderedPair<>("hello", "world");
要?jiǎng)?chuàng)建泛型接口,請(qǐng)遵循與創(chuàng)建泛型類(lèi)相同的約定。
參數(shù)化類(lèi)型你還可以使用參數(shù)化類(lèi)型(即List
OrderedPair上一篇:為什么要使用泛型? 下一篇:泛型原始類(lèi)型> p = new OrderedPair<>("primes", new Box (...));
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/72926.html
Java? 教程 Java教程是為JDK 8編寫(xiě)的,本頁(yè)面中描述的示例和實(shí)踐沒(méi)有利用在后續(xù)版本中引入的改進(jìn)。 Java教程是希望使用Java編程語(yǔ)言創(chuàng)建應(yīng)用程序的程序員的實(shí)用指南,其中包括數(shù)百個(gè)完整的工作示例和數(shù)十個(gè)課程,相關(guān)課程組被組織成教程。 覆蓋基礎(chǔ)知識(shí)的路徑 這些教程以書(shū)籍的形式提供,如Java教程,第六版,前往Amazon.com購(gòu)買(mǎi)。 入門(mén) 介紹Java技術(shù)和安裝Java開(kāi)發(fā)軟件并使用...
類(lèi)型推斷 類(lèi)型推斷是Java編譯器查看每個(gè)方法調(diào)用和相應(yīng)聲明的能力,以確定使調(diào)用適用的類(lèi)型參數(shù),推理算法確定參數(shù)的類(lèi)型,如果可用,還確定分配或返回結(jié)果的類(lèi)型,最后,推理算法嘗試查找適用于所有參數(shù)的最具體類(lèi)型。 為了說(shuō)明最后一點(diǎn),在下面的示例中,推斷確定傳遞給pick方法的第二個(gè)參數(shù)是Serializable類(lèi)型: static T pick(T a1, T a2) { return a2; } ...
泛型原始類(lèi)型 原始類(lèi)型是沒(méi)有任何類(lèi)型參數(shù)的泛型類(lèi)或接口的名稱(chēng),例如,給定Box泛型類(lèi): public class Box { public void set(T t) { /* ... */ } // ... } 要?jiǎng)?chuàng)建參數(shù)化類(lèi)型的Box,請(qǐng)為形式類(lèi)型參數(shù)T提供實(shí)際類(lèi)型參數(shù): Box intBox = new Box(); 如果省略實(shí)際的類(lèi)型參數(shù),則創(chuàng)建一個(gè)原始類(lèi)型Box: Box...
泛型 在任何重要的軟件項(xiàng)目中,bug都是不可避免的,仔細(xì)的規(guī)劃、編程和測(cè)試可以幫助減少它們的普遍性,但是它們總會(huì)在某個(gè)地方以某種方式潛入你的代碼,隨著新功能的引入以及你的代碼庫(kù)在規(guī)模和復(fù)雜性方面的增長(zhǎng),這一點(diǎn)變得尤為明顯。 幸運(yùn)的是,一些錯(cuò)誤比其他錯(cuò)誤更容易被發(fā)現(xiàn),例如,編譯時(shí)錯(cuò)誤可以在早期檢測(cè)到,你可以使用編譯器的錯(cuò)誤消息來(lái)確定問(wèn)題所在并立即修復(fù)它。但是,運(yùn)行時(shí)錯(cuò)誤可能會(huì)更成問(wèn)題,它們并不總是立...
泛型方法 泛型方法是引入其自己的類(lèi)型參數(shù)的方法,這類(lèi)似于聲明泛型類(lèi)型,但類(lèi)型參數(shù)的范圍僅限于聲明它的方法,允許使用靜態(tài)和非靜態(tài)泛型方法,以及泛型類(lèi)構(gòu)造函數(shù)。 泛型方法的語(yǔ)法包括類(lèi)型參數(shù)列表,在尖括號(hào)內(nèi),它出現(xiàn)在方法的返回類(lèi)型之前,對(duì)于靜態(tài)泛型方法,類(lèi)型參數(shù)部分必須出現(xiàn)在方法的返回類(lèi)型之前。 Util類(lèi)包含一個(gè)泛型方法compare,它比較兩個(gè)Pair對(duì)象: public class Util { ...
閱讀 1013·2021-11-25 09:43
閱讀 1676·2019-08-30 13:59
閱讀 1602·2019-08-30 11:22
閱讀 2131·2019-08-30 11:06
閱讀 1306·2019-08-28 17:51
閱讀 3732·2019-08-26 12:12
閱讀 785·2019-08-26 12:11
閱讀 453·2019-08-26 12:10