泛型是通用编程的设施,它扩展了Java类型的系统,以允许一种类型或者方法在提供编译时类型安全的同时在各种类型的对象上运行。
特别是,Java Collections框架支持泛型,以指定存储在集合实例中的对象类型。
创建泛型类
泛型使能够将其他类和接口作为类型参数携带其他类,接口和方法。
此示例使用Generic Class Param进行单个类型参数T,由角括号(<>)分隔:
public class Param {
private T value;
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}
要实例化此类,请提供代替T的类型参数。
例如,整数:
Param integerParam = new Param();
类型参数可以是任何引用类型,包括数组和其他通用类型:
Param stringArrayParam; Param int2dArrayParam; Param> objectNestedParam;
在Java SE 7及更高版本中,可以用名为Diamond的空组参数(<>)替换类型参数:
Version ≥ Java SE 7 Param integerParam = new Param<>();
与其他标识符不同,类型参数没有命名约束。
然而,他们的名字通常是第一个字母大写(即使在正式的JavaDocs中也是如此。)
例如,T表示“type”,E表示“element”,K/V表示“key”/“value”。
Extending a generic class
public abstract class AbstractParam {
private T value;
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}
AbstractParam是一个用T的类型参数声明的抽象类。
当扩展此类时,该类型参数可以由写入中的类型参数替换为<>,或者类型参数可以保持不变。
在下面的第一个和第二个示例中,字符串和整数替换类型参数。
在第三示例中,类型参数保持不变。
第四个示例根本不使用泛型,因此如果类具有对象参数,它类似于它。
编译器将警告AbstractParam是原始类型,但它将编译ObjectParam类。
第五个示例有2型参数(请参阅下面的“多种类型参数”),选择第二个参数,因为传递给超类的类型参数。
public class Email extends AbstractParam {
//…
}
public class Age extends AbstractParam {
//…
}
public class Height extends AbstractParam {
//…
}
public class ObjectParam extends AbstractParam {
//…
}
public class MultiParam extends AbstractParam {
//…
}
下面是使用时的情况:
Email email = new Email();
email.setValue("jack@onitroad");
String retrievedEmail = email.getValue();
Age age = new Age();
age.setValue(25);
Integer retrievedAge = age.getValue();
int autounboxedAge = age.getValue();
Height heightInInt = new Height<>();
heightInInt.setValue(125);
Height heightInFloat = new Height<>();
heightInFloat.setValue(120.3f);
MultiParam multiParam = new MultiParam<>();
multiParam.setValue(3.3);
请注意,在Email类中,t getValue()方法就好像它具有字符串getValue()的签名,并且void setValue(t)方法就好像被声明了void setValue(String)一样。
还可以使用空卷括号({})的匿名内部类实例化:
AbstractParam height = new AbstractParam(){};
height.setValue(198.6);
泛型中的多种类型参数
Java提供了在通用类或者接口中使用多个类型参数的能力。
通过在尖括号之间放置逗号分隔的类型列表,可以在类或者接口中使用多个类型参数。
例子:
public class MultiGenericParam {
private T firstParam;
private S secondParam;
public MultiGenericParam(T firstParam, S secondParam) {
this.firstParam = firstParam;
this.secondParam = secondParam;
}
public T getFirstParam() {
return firstParam;
}
public void setFirstParam(T firstParam) {
this.firstParam = firstParam;
}
public S getSecondParam() {
return secondParam;
}
public void setSecondParam(S secondParam) {
this.secondParam = secondParam;
}
}
使用可以如下所示:
MultiGenericParam aParam = new MultiGenericParam("value1",
"value2");
MultiGenericParam dayOfWeekDegrees = new MultiGenericParam(1,
2.6);
