Java中的泛型
泛型的概念
Java 泛型本质上是参数化类型,使得所操作的数据类型被指定为一个参数。
目的是支持创建可以按类型进行参数化的类。可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法的形式参数是运行时传递的值的占位符一样。
泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。
泛型的好处如下:
- 类型安全
- 消除强制类型转换
类型通配符
为了表示各种泛型List的父类,我们需要使用类型通配符,类型通配符是一个问号(?),将一个问号作为类型实参传给List集合,List<?>(意思是未知类型元素的List)。这个问号(?)被称作通配符,它的元素类型可以匹配任何类型。例如下面的代码。
实例
import java.util.ArrayList;
import java.util.List;
public class Demo{
public static void getData(List<?> data){
System.out.println("data:"+data.get(0));
}
public static void main(String[] args){
ArrayList<String> name=new ArrayList<String>();
ArrayList<Float> grade=new ArrayList<Float>();
ArrayList<Character> sex=new ArrayList<Character>();
name.add("张三");
grade.add(75.5f);
sex.add('男');
getData(name);
getData(grade);
getData(sex);
}
}
运行结果
data:张三
data:75.5
data:男
如何给通配符设置相应的上下限
上限:<? extends T>
下限:<? super T>
实例
import java.util.ArrayList;
import java.util.List;
public class Demo{
public static void getData(List<? extends String> data){
System.out.println("data:"+data.get(0));
}
public static void main(String[] args){
ArrayList<String> name=new ArrayList<String>();
ArrayList<Float> grade=new ArrayList<Float>();
ArrayList<Character> sex=new ArrayList<Character>();
name.add("张三");
grade.add(75.5f);
sex.add('男');
getData(name);
//getData(grade);
//getData(sex);
}
}
运行结果
data:张三
如果把注释去掉会出现编译出错
泛型方法
在Java中提供了泛型方法,如果一个方法被声明成泛型方法,那么它将拥有一个或多个类型参数。
定义泛型方法的格式
[访问权限修饰符][static][final]<类型参数列表>返回值类型方法名([形式参数列表])
实例
import java.util.ArrayList;
import java.util.List;
public class Demo{
public static <T> void printData(T[] data){
for(T t:data){
System.out.print(t+" ");
}
}
public static void main(String[] args){
Integer[] in={1,2,3,4,5,6};
Character[] ch={'t','y','f'};
String[] st={"tgv","vbn"};
System.out.println("整形数组:");
printData(in);
System.out.println();
System.out.println("字符数组:");
printData(ch);
System.out.println();
System.out.println("字符串数组:");
printData(st);
System.out.println();
}
}
运行结果
整形数组:
1 2 3 4 5 6
字符数组:
t y f
字符串数组:
tgv vbn
如果要设置泛型的限制用如下的格式
[访问权限修饰符][static][final]<T extends type>返回值类型方法名([形式参数列表])
泛型类
泛型类的声明和非泛型类的声明类似,除了在类名后面添加了类型参数声明部分。
实例
public class Demo<T>{
private T t;
public Demo(T t){
this.t=t;
}
public T get(){
return this.t;
}
public static void main(String[] args){
Demo<Integer> d1=new Demo<Integer>(2);
Demo<String> d2=new Demo<String>("rt");
System.out.println("整型:"+d1.get());
System.out.println("字符串:"+d2.get());
}
}
运行结果
整型:2
字符串:rt
使用泛型的一些注意事项:
- 在代码中避免泛型类和原始类型的混用。比如List和List不应该共同使用,因为这样会产生一些编译器警告和潜在的运行时异常。
- 在使用带通配符的泛型类的时候,需要明确通配符所代表的一组类型的概念。由于具体的类型是未知的,因此很多操作是不允许的。
- 不要忽视编译器给出的警告信息。