前言
Java 泛型入门,泛型的含义及实现。
一、泛型
1、含义
1)数据类型参数化,这样就可以一类多用等等。
2)数据类型只能是引用类型,这也是基本数据类型需要包装的便捷之处。
2、实现
用一个占位符替代,可用于类、接口、方法,分别对应于泛型类、泛型接口、泛型方法。
public class TestGeneric<T1, T2> {
private T1 a;
private T2 b;
public void setA(T1 a) {
this.a = a;
}
public void setB(T2 b) {
this.b = b;
}
public T1 getA() {
return a;
}
public T2 getB() {
return b;
}
//泛型与可变参数
public <T5> void getArgs(T5... args) {
for (T5 arg : args) {
System.out.println(arg);
}
}
}
interface Generic<T> {
T getName();
}
3、好处
1)不用强制转换类,代码可读性更好。如果不使用泛型,则是Object,需要很多instanceof来判断类类型及强制转换,而这个转化过程可能在运行时出错。
2)明确了泛型类型,只要编译通过,则不会出现ClassCastException异常。
注:类型擦除,编译时,会替换成Object,再强转。对于JVM,没有泛型的概念。
3)方便写代码,只要编译时不出错,那么运行时就不会出错,较安全。
二、定义泛型
1、基本定义
1)泛型类
用的时候才确定类型
2)泛型接口
3)泛型方法
A.非静态方法
泛型定义在public与返回值之间,可以用类的泛型。
B.静态方法
泛型定义在static与返回值之间,但是不可以用方法的泛型。
2、可变参数
//泛型与可变参数
public <T5> void getArgs(T5... args) {
for (T5 arg : args) {
System.out.println(arg);
}
}
类似于泛型方法。
3、通配符与上下限定
当把泛型类对象传入方法,作为参数列表时,可以用?来占位,当然不是一定要?,任何一个符合都可以,只是默认?表示可变类型。
//通配符和上下限定,当前类型或当前类的父类和子类.这只适合方法,不适合类
public void show(GenericS<?> a){
System.out.println(a);
}
通过extends、super来进行传入类类型的限定。
public void show2(GenericS<? extends Number> a){
System.out.println(a);
}
public void show3(GenericS<? super Integer> a){
System.out.println(a);
}
注:
1)extends:限定的类是子类及其自己。
2)super:限定的类是自己及其父类。
3)泛型类,泛型接口只能用extends,不能用super。
总结
1)泛型定义、实现、优点、通配符与上下限定。
参考文献
[1] Java SE 高淇
附录
[1] 完整代码
package com.xhu.java;
public class TestGeneric<T1, T2> {
private T1 a;
private T2 b;
public void setA(T1 a) {
this.a = a;
}
public void setB(T2 b) {
this.b = b;
}
public T1 getA() {
return a;
}
public T2 getB() {
return b;
}
//泛型与可变参数
public <T5> void getArgs(T5... args) {
for (T5 arg : args) {
System.out.println(arg);
}
}
//通配符和上下限定,当前类型或当前类的父类和子类.这只适合方法,不适合类
public void show(GenericS<?> a){
System.out.println(a);
}
public void show2(GenericS<? extends Number> a){
System.out.println(a);
}
public void show3(GenericS<? super Integer> a){
System.out.println(a);
}
public static void main(String[] args) {
TestGeneric<Integer, Double> tg = new TestGeneric<>();
tg.setA(1);
tg.setB(1d);
System.out.println(tg.getA());
Generic g = new GenericC();
tg.get(1);
//可变参数
Integer[] nums = new Integer[]{1,2,3};
String[] strs = new String[]{"a","b","c"};
//通配符和上下限定
GenericS<Integer> gc = new GenericS<>();
tg.show(gc);
}
public <T3> T3 get(T3 a) {
return a;
}
//静态方法无法访问类上的泛型
public static <T4> void getStatic(T4 n) {
System.out.println(n);
}
static class GenericS<T> {
}
}
interface Generic<T> {
T getName();
}
class GenericC implements Generic<String> {
@Override
public String getName() {
return null;
}
}