不同Java泛型構(gòu)造函數(shù)的詳解
1.概述
我們之前討論過(guò)Java Generics的基礎(chǔ)知識(shí)。在本文中,我們將了解Java中的通用構(gòu)造函數(shù)。
泛型構(gòu)造函數(shù)是至少需要有一個(gè)泛型類型參數(shù)的構(gòu)造函數(shù)。我們將看到泛型構(gòu)造函數(shù)并不都是在泛型類中出現(xiàn)的,而且并非所有泛型類中的構(gòu)造函數(shù)都必須是泛型。
2.非泛型類
首先,先寫一個(gè)簡(jiǎn)單的類:Entry,它不是泛型類:
public class Entry {
private String data;
private int rank;
}
在這個(gè)類中,我們將添加兩個(gè)構(gòu)造函數(shù):一個(gè)帶有兩個(gè)參數(shù)的基本構(gòu)造函數(shù)和一個(gè)通用構(gòu)造函數(shù)。
2.1 基本構(gòu)造器
Entry第一個(gè)構(gòu)造函數(shù):帶有兩個(gè)參數(shù)的簡(jiǎn)單構(gòu)造函數(shù):
public Entry(String data, int rank) {
this.data = data;
this.rank = rank;
}
現(xiàn)在,讓我們使用這個(gè)基本構(gòu)造函數(shù)來(lái)創(chuàng)建一個(gè)Entry對(duì)象
@Test
public void givenNonGenericConstructor_whenCreateNonGenericEntry_thenOK() {
Entry entry = new Entry("sample", 1);
assertEquals("sample", entry.getData());
assertEquals(1, entry.getRank());
}
2.2 泛型構(gòu)造器
接下來(lái),第二個(gè)構(gòu)造器是泛型構(gòu)造器:
public <E extends Rankable & Serializable> Entry(E element) {
this.data = element.toString();
this.rank = element.getRank();
}
雖然Entry類不是通用的,但它有一個(gè)參數(shù)為E的泛型構(gòu)造函數(shù)。
泛型類型E是受限制的,應(yīng)該實(shí)現(xiàn)Rankable和Serializable接口。
現(xiàn)在,讓我們看看Rankable接口,下面是其中一個(gè)方法:
public interface Rankable {
public int getRank();
}
假設(shè)我們有一個(gè)實(shí)現(xiàn)Rankable接口的類——Product
public class Product implements Rankable, Serializable {
private String name;
private double price;
private int sales;
public Product(String name, double price) {
this.name = name;
this.price = price;
}
@Override
public int getRank() {
return sales;
}
}
然后我們可以使用泛型構(gòu)造函數(shù)和Product創(chuàng)建Entry對(duì)象:
@Test
public void givenGenericConstructor_whenCreateNonGenericEntry_thenOK() {
Product product = new Product("milk", 2.5);
product.setSales(30);
Entry entry = new Entry(product);
assertEquals(product.toString(), entry.getData());
assertEquals(30, entry.getRank());
}
3.泛型類
接下來(lái),我們看一下泛型類:GenericEntry
public class GenericEntry<T> {
private T data;
private int rank;
}
我們將在此類中添加與上一節(jié)相同的兩種類型的構(gòu)造函數(shù)。
3.1 基礎(chǔ)構(gòu)造器
首先,讓我們?yōu)镚enericEntry類編寫一個(gè)簡(jiǎn)單的非泛型構(gòu)造函數(shù):
public GenericEntry(int rank) {
this.rank = rank;
}
盡管GenericEntry是泛型類,但這是一個(gè)簡(jiǎn)單的,沒(méi)有任何參數(shù)的構(gòu)造函數(shù)。
現(xiàn)在,我們可以使用此構(gòu)造函數(shù)來(lái)創(chuàng)建GenericEntry:
@Test
public void givenNonGenericConstructor_whenCreateGenericEntry_thenOK() {
GenericEntry<String> entry = new GenericEntry<String>(1);
assertNull(entry.getData());
assertEquals(1, entry.getRank());
}
3.2 泛型構(gòu)造器
接下來(lái),在類中添加第二個(gè)構(gòu)造函數(shù):
public GenericEntry(T data, int rank) {
this.data = data;
this.rank = rank;
}
這是一個(gè)泛型構(gòu)造函數(shù),它有一個(gè)泛型類型T的數(shù)據(jù)參數(shù)。注意,我們不需要在構(gòu)造函數(shù)聲明中添加,因?yàn)樗请[含的。
現(xiàn)在,讓我們測(cè)試一下通用構(gòu)造函數(shù):
@Test
public void givenGenericConstructor_whenCreateGenericEntry_thenOK() {
GenericEntry<String> entry = new GenericEntry<String>("sample", 1);
assertEquals("sample", entry.getData());
assertEquals(1, entry.getRank());
}
4.不同類型的泛型構(gòu)造函數(shù)
在泛型類中,還有一個(gè)構(gòu)造函數(shù),其泛型類型與類的泛型類型不同:
public <E extends Rankable & Serializable> GenericEntry(E element) {
this.data = (T) element;
this.rank = element.getRank();
}
GenericEntry構(gòu)造函數(shù)有類型為E的參數(shù),該參數(shù)與T類型不同。讓我們看看它的實(shí)際效果:
@Test
public void givenGenericConstructorWithDifferentType_whenCreateGenericEntry_thenOK() {
Product product = new Product("milk", 2.5);
product.setSales(30);
GenericEntry<Serializable> entry = new GenericEntry<Serializable>(product);
assertEquals(product, entry.getData());
assertEquals(30, entry.getRank());
}
注意:在示例中,我們使用Product(E)創(chuàng)建Serializable(T)類型的GenericEntry,只有當(dāng)類型E的參數(shù)可以轉(zhuǎn)換為T時(shí),我們才能使用此構(gòu)造函數(shù)。
5.多種泛類型
接下來(lái),我們有兩個(gè)泛型類型參數(shù)的泛型類MapEntry:
public class MapEntry<K, V> {
private K key;
private V value;
public MapEntry(K key, V value) {
this.key = key;
this.value = value;
}
}
MapEntry有一個(gè)兩個(gè)參數(shù)的泛型構(gòu)造函數(shù),每個(gè)參數(shù)都是不同的類型。讓我們用一個(gè)簡(jiǎn)單的單元測(cè)試測(cè)試一下:
@Test
public void givenGenericConstructor_whenCreateGenericEntryWithTwoTypes_thenOK() {
MapEntry<String,Integer> entry = new MapEntry<String,Integer>("sample", 1);
assertEquals("sample", entry.getKey());
assertEquals(1, entry.getValue().intValue());
}
6.通配符
最后,我們可以在泛型構(gòu)造函數(shù)中使用通配符:
public GenericEntry(Optional<? extends Rankable> optional) {
if (optional.isPresent()) {
this.data = (T) optional.get();
this.rank = optional.get().getRank();
}
}
在這兒,我們?cè)贕enericEntry構(gòu)造函數(shù)中使用通配符來(lái)綁定Optional類型:
@Test
public void givenGenericConstructorWithWildCard_whenCreateGenericEntry_thenOK() {
Product product = new Product("milk", 2.5);
product.setSales(30);
Optional<Product> optional = Optional.of(product);
GenericEntry<Serializable> entry = new GenericEntry<Serializable>(optional);
assertEquals(product, entry.getData());
assertEquals(30, entry.getRank());
}
請(qǐng)注意,我們應(yīng)該能夠?qū)⒖蛇x參數(shù)類型(Product示例)轉(zhuǎn)換為GenericEntry類型(Serializable示例)。
7.結(jié)束語(yǔ)
在本文中,我們學(xué)習(xí)了如何在泛型和非泛型類中定義和使用泛型構(gòu)造函數(shù)。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Java 無(wú)參數(shù)構(gòu)造函數(shù)的應(yīng)用
- java構(gòu)造函數(shù)示例(構(gòu)造方法)
- Java構(gòu)造函數(shù)的相互調(diào)用代碼示例
- Java 重載、重寫、構(gòu)造函數(shù)的實(shí)例詳解
- java枚舉類的構(gòu)造函數(shù)實(shí)例詳解
- Java構(gòu)造函數(shù)與普通函數(shù)用法詳解
- 關(guān)于java中構(gòu)造函數(shù)的一些知識(shí)詳解
- 深入理解Java中的構(gòu)造函數(shù)引用和方法引用
- Java序列化中子類、父類構(gòu)造函數(shù)問(wèn)題實(shí)例分析
- Java的無(wú)參構(gòu)造函數(shù)用法實(shí)例分析
相關(guān)文章
Intellij?IDEA根據(jù)maven依賴名查找它是哪個(gè)pom.xml引入的(圖文詳解)
這篇文章主要介紹了Intellij?IDEA根據(jù)maven依賴名查找它是哪個(gè)pom.xml引入的,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-08-08
java web開(kāi)發(fā)中大量數(shù)據(jù)導(dǎo)出Excel超時(shí)(504)問(wèn)題解決
開(kāi)發(fā)測(cè)試時(shí)候?qū)霐?shù)據(jù)遇到大數(shù)據(jù)導(dǎo)入的問(wèn)題,整理了下,需要的朋友可以參考下2017-04-04
淺談java對(duì)象結(jié)構(gòu) 對(duì)象頭 Markword
這篇文章主要介紹了淺談java對(duì)象結(jié)構(gòu) 對(duì)象頭 Markword,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-10-10
Spring的IOC容器實(shí)例化bean的方式總結(jié)
IOC容器實(shí)例化bean的三種方式:構(gòu)造方法、靜態(tài)工廠、實(shí)例工廠,本文將通過(guò)代碼示例給大家詳細(xì)講解一下這三種方式,對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-01-01
MyBatis-Plus實(shí)現(xiàn)公共字段自動(dòng)填充功能詳解
在開(kāi)發(fā)中經(jīng)常遇到多個(gè)實(shí)體類有共同的屬性字段,這些字段屬于公共字段,也就是很多表中都有這些字段,能不能對(duì)于這些公共字段在某個(gè)地方統(tǒng)一處理,來(lái)簡(jiǎn)化開(kāi)發(fā)呢?MyBatis-Plus就提供了這一功能,本文就來(lái)為大家詳細(xì)講講2022-08-08
Java網(wǎng)絡(luò)編程實(shí)現(xiàn)的簡(jiǎn)單端口掃描器示例
這篇文章主要介紹了Java網(wǎng)絡(luò)編程實(shí)現(xiàn)的簡(jiǎn)單端口掃描器,涉及Java網(wǎng)絡(luò)編程Socket組建、swing組建及多線程相關(guān)操作技巧,需要的朋友可以參考下2018-04-04
java 中的instanceof用法詳解及instanceof是什么意思(推薦)
instanceof 是 Java 的保留關(guān)鍵字。它的作用是測(cè)試它左邊的對(duì)象是否是它右邊的類的實(shí)例,返回 boolean 的數(shù)據(jù)類型。接下來(lái)通過(guò)本文給大家介紹java 中的instanceof用法詳解及instanceof是什么意思,需要的朋友參考下吧2017-11-11

