内容简介:我们之前讨论过首先,先写一个简单的类:Entry,它不是泛型类:在这个类中,我们将添加两个构造函数:一个带有两个参数的基本构造函数和一个通用构造函数。
我们之前讨论过 Java Generics
的基础知识。在本文中,我们将了解 Java 中的通用构造函数。 泛型构造函数是至少需要有一个泛型类型参数的构造函数。我们将看到泛型构造函数并不都是在泛型类中出现的,而且并非所有泛型类中的构造函数都必须是泛型。
2.非泛型类
首先,先写一个简单的类:Entry,它不是泛型类:
public class Entry { private String data; private int rank; } 复制代码
在这个类中,我们将添加两个构造函数:一个带有两个参数的基本构造函数和一个通用构造函数。
2.1 基本构造器
Entry
第一个构造函数:带有两个参数的简单构造函数:
public Entry(String data, int rank) { this.data = data; this.rank = rank; } 复制代码
现在,让我们使用这个基本构造函数来创建一个 Entry
对象
@Test public void givenNonGenericConstructor_whenCreateNonGenericEntry_thenOK() { Entry entry = new Entry("sample", 1); assertEquals("sample", entry.getData()); assertEquals(1, entry.getRank()); } 复制代码
2.2 泛型构造器
接下来,第二个构造器是泛型构造器:
public <E extends Rankable & Serializable> Entry(E element) { this.data = element.toString(); this.rank = element.getRank(); } 复制代码
虽然 Entry
类不是通用的,但它有一个参数为 E
的泛型构造函数。
泛型类型 E
是受限制的,应该实现 Rankable
和 Serializable
接口。
现在,让我们看看 Rankable
接口,下面是其中一个方法:
public interface Rankable { public int getRank(); } 复制代码
假设我们有一个实现 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; } } 复制代码
然后我们可以使用泛型构造函数和 Product
创建 Entry
对象:
@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.泛型类
接下来,我们看一下泛型类: GenericEntry
public class GenericEntry<T> { private T data; private int rank; } 复制代码
我们将在此类中添加与上一节相同的两种类型的构造函数。
3.1 基础构造器
首先,让我们为 GenericEntry
类编写一个简单的非泛型构造函数:
public GenericEntry(int rank) { this.rank = rank; } 复制代码
尽管 GenericEntry
是泛型类,但这是一个简单的,没有任何参数的构造函数。
现在,我们可以使用此构造函数来创建 GenericEntry
:
@Test public void givenNonGenericConstructor_whenCreateGenericEntry_thenOK() { GenericEntry<String> entry = new GenericEntry<String>(1); assertNull(entry.getData()); assertEquals(1, entry.getRank()); } 复制代码
3.2 泛型构造器
接下来,在类中添加第二个构造函数:
public GenericEntry(T data, int rank) { this.data = data; this.rank = rank; } 复制代码
这是一个泛型构造函数,它有一个泛型类型T的数据参数。注意,我们不需要在构造函数声明中添加,因为它是隐含的。
现在,让我们测试一下通用构造函数:
@Test public void givenGenericConstructor_whenCreateGenericEntry_thenOK() { GenericEntry<String> entry = new GenericEntry<String>("sample", 1); assertEquals("sample", entry.getData()); assertEquals(1, entry.getRank()); } 复制代码
4.不同类型的泛型构造函数
在泛型类中,还有一个构造函数,其泛型类型与类的泛型类型不同:
public <E extends Rankable & Serializable> GenericEntry(E element) { this.data = (T) element; this.rank = element.getRank(); } 复制代码
GenericEntry
构造函数有类型为 E
的参数,该参数与 T
类型不同。让我们看看它的实际效果:
@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)
创建 Serializable(T)
类型的 GenericEntry
,只有当类型 E
的参数可以转换为 T
时,我们才能使用此构造函数。
5.多种泛类型
接下来,我们有两个泛型类型参数的泛型类 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
有一个两个参数的泛型构造函数,每个参数都是不同的类型。让我们用一个简单的单元测试测试一下:
@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.通配符
最后,我们可以在泛型构造函数中使用通配符:
public GenericEntry(Optional<? extends Rankable> optional) { if (optional.isPresent()) { this.data = (T) optional.get(); this.rank = optional.get().getRank(); } } 复制代码
在这儿,我们在 GenericEntry
构造函数中使用通配符来绑定 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()); } 复制代码
请注意,我们应该能够将可选参数类型(Product示例)转换为 GenericEntry
类型(Serializable示例)。
7.结束语
在本文中,我们学习了如何在泛型和非泛型类中定义和使用泛型构造函数。
完整的源代码可以在 GitHub
获取(点击查看原文)。
原文链接: www.baeldung.com/java-generi…
作者:baeldung
译者:Emma
关注公众号:锅外的大佬
每日推送国外优秀的技术翻译文章,励志帮助国内的开发者更好地成长!
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- php如何实现session,自己实现session,laravel如何实现session
- AOP如何实现及实现原理
- webpack 实现 HMR 及其实现原理
- Docker实现原理之 - OverlayFS实现原理
- 为什么实现 .NET 的 ICollection 集合时需要实现 SyncRoot 属性?如何正确实现这个属性?
- 自己实现集合框架(十):顺序栈的实现
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
An Introduction to Probability Theory and Its Applications
William Feller / Wiley / 1991-1-1 / USD 120.00
Major changes in this edition include the substitution of probabilistic arguments for combinatorial artifices, and the addition of new sections on branching processes, Markov chains, and the De Moivre......一起来看看 《An Introduction to Probability Theory and Its Applications》 这本书的介绍吧!