欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

不同Java泛型构造函数的详解

程序员文章站 2022-06-29 22:46:54
1.概述 我们之前讨论过java generics的基础知识。在本文中,我们将了解java中的通用构造函数。 泛型构造函数是至少需要有一个泛型类型参数的构造函数。我...

1.概述

我们之前讨论过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.结束语

在本文中,我们学习了如何在泛型和非泛型类中定义和使用泛型构造函数。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。