当前位置: 移动技术网 > IT编程>开发语言>Java > 不同Java泛型构造函数的详解

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

2019年07月19日  | 移动技术网IT编程  | 我要评论

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.结束语

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

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网