一、泛型是什么?
Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
二、为什么使用泛型?
在Java增加泛型之前,泛型程序设计使用继承来实现。但是,这样做的坏处是:
- 需要强制转换
- 可向集合添加任意类型的对象,存在风险
使用泛型时,在编译时就可以对非法的类型进行检测。
List list = new ArrayList();
list.add("str");
list.add(1);
// 遍历方法
for (int i=0; i<list.size(); i++) {
String string = (String)list.get(i); // 抛出ClassCastException异常
System.out.println(string);
}
List<String> list = new ArrayList<>();
list.add("str");
list.add(1); // 编译不通过
// 遍历方法
for (int i=0; i<list.size(); i++) {
String string = (String)list.get(i);
System.out.println(string);
}
三、泛型的使用
(一)泛型作为方法参数
// 普通方法参数
public static void main(String[] args) {
TestMain2 testMain2 = new TestMain2();
List<String> list = new ArrayList<String>();
list.add("1");
list.add("2");
list.add("3");
testMain2.showList(list);
}
public void showList(List<String> list) {
for (String string:list) {
System.out.println(string);
}
}
public static void main(String[] args) {
TestMain3 testMain3 = new TestMain3();
Animal animal1 = new Animal("动物1");
Animal animal2 = new Animal("动物2");
Animal animal3 = new Animal("动物3");
Cat cat1 = new Cat("猫1");
Cat cat2 = new Cat("猫2");
Cat cat3 = new Cat("猫3");
CatSon catSon1 = new CatSon("猫子1");
CatSon catSon2 = new CatSon("猫子2");
CatSon catSon3 = new CatSon("猫子3");
List<Animal> animals = new ArrayList<>();
List<Cat> cats = new ArrayList<>();
List<CatSon> catSons = new ArrayList<>();
animals.add(animal1);
animals.add(animal2);
animals.add(animal3);
cats.add(cat1);
cats.add(cat2);
cats.add(cat3);
catSons.add(catSon1);
catSons.add(catSon2);
catSons.add(catSon3);
testMain3.show1(animals); // 编译不通过
testMain3.show1(cats);
testMain3.show1(catSons);
testMain3.show2(animals);
testMain3.show2(cats);
testMain3.show2(catSons); // 编译不通过
}
// 泛型上限为Cat
public void show1(List<? extends Cat> list) {
for (int i=0; i<list.size(); i++) {
System.out.println(list.get(i));
}
}
// 泛型下限为Cat
public void show2(List<? super Cat> list) {
for (int i=0; i<list.size(); i++) {
System.out.println(list.get(i));
}
}
(二)自定义泛型类
public class TestClass<T> {
private T msg;
public TestClass(){
}
public TestClass(T msg){
this.setMsg(msg);
}
public T getMsg() {
return msg;
}
public void setMsg(T msg) {
this.msg = msg;
}
public static void main(String[] args) {
TestClass<Integer> testClass = new TestClass<>(1);
// TestClass<Integer> testClass2 = new TestClass<>("测试"); // 编译不通过
TestClass<String> testClass3 = new TestClass<>("测试");
System.out.println(testClass.getMsg());
System.out.println(testClass3.getMsg());
}
}
(三)自定义泛型方法
- 泛型方法不一定要定义在泛型类里
修饰符 <T> 返回值 方法名(参数类型 参数名){
方法实现功能
}
public <T> void printValue(T t){
System.out.println(t);
}
(四)自定义泛型接口
public interface Test<T> {
public T myTest();
}
public class TestIm1 implements ITest<T> { // 编译报错
@Override
public T myTest() {
return null;
}
}
public class TestIm1<T> implements ITest<T> { // 编译正常
@Override
public T myTest() {
return null;
}
}
public class TestIm1 implements ITest<String> { // 编译正常
@Override
public String myTest() {
return null;
}
}