【学习笔记】泛型
泛型概述
-
Java 泛型是JDK1.5中引入的一个新特性,其本质是参数化类型,把类型作为参数传递
-
常见形式有泛型类、泛型接口、泛型方法
-
语法:
-
<T,...> T称为类型占位符,表示一种引用类型
-
-
好处:
-
提高代码的重用性
-
防止类型转换异常,提高代码的安全性
-
泛型类
-
语法:在类名的后面加< T > T表示占位符,如果要写多个就用逗号隔开
-
使用方法:
-
创建变量
-
注意:不能 new 一个 对象,因为我们不知道这个T到底是什么类型,所以它有没有构造方法,以及构造方法能不能访问,我们都不清楚,所以不能直接new 一个对象
-
-
作为方法的形式参数
-
作为方法的返回值
-
package com.generic;
public class MyGeneric<T> {
//创建变量
T t;
//作为方法的参数
public void show(T t){
System.out.println(t);
}
//作为方法的返回值
public T getT(){
return t;
}
}
-
使用泛型类创建对象
package com.generic;
public class TestGeneric {
public static void main(String[] args) {
//使用泛型类创建对象
MyGeneric<String> myGeneric1 = new MyGeneric<>();
myGeneric1.t = "hello";
myGeneric1.show("java is good");
String str = myGeneric1.getT();
System.out.println(str);
System.out.println("-------------------");
MyGeneric<Integer> myGeneric2 = new MyGeneric<>();
myGeneric2.t = 100;
myGeneric2.show(200);
Integer i = myGeneric2.getT();
System.out.println(i);
}
}
-
注意:
-
泛型只能使用引用类型
-
不同的泛型类型对象不能相互赋值
-
也就是说,在上面的例子中 不能这样操作 myGeneric1 = myGeneric2
-
-
泛型接口
-
语法:接口名< T >
-
在接口中,我们可以定义静态常量和抽象方法
-
我们可以使用泛型来作为抽象方法的参数和返回值
-
但是不能使用泛型来定义静态常量,因为常量要求在定义时必须初始化,我们不知道这个泛型具体是什么类型,没有办法给它初始化,所以不可以定义静态常量
-
-
在实现泛型接口时,有两种情况:
-
在实现接口时,我们已经确定了类型
-
package com.generic; public class MyInterfaceImpl implements MyInterface<String>{ @Override public String server(String s) { System.out.println(s); return s; } }
package com.generic; public class TestGeneric { public static void main(String[] args) { MyInterfaceImpl myInterface1 = new MyInterfaceImpl(); myInterface1.server("大家好"); } }
-
-
第二种情况是:我们在实现接口时,不确定这个类型,我们可以把这个实现类也变成泛型类,这个时候,实现类所对应的泛型就是接口所对应的泛型
-
package com.generic; public class MyInterfaceImpl2<T> implements MyInterface<T>{ @Override public T server(T t) { System.out.println(t); return t; } }
MyInterfaceImpl2<Integer> myInterface2 = new MyInterfaceImpl2(); myInterface2.server(20000);
-
-
泛型方法
-
语法:在返回值前面加 < T >
-
所定义的泛型方法,只能在该方法内使用,不能在方法外使用
-
可以作为该方法的参数和返回值,也可以定义变量
package com.generic;
public class MyGenericMethod {
//泛型方法
public <T> T show(T t){
System.out.println(t);
return t;
}
}
-
它的类型是根据你传递的参数来决定的
package com.generic;
public class TestGeneric {
public static void main(String[] args) {
MyGenericMethod method = new MyGenericMethod();
method.show("hello");
method.show("200");
}
}
-
在这个案例中,我们可以体会到泛型的好处之一就是:提高代码的重用性
如果不使用泛型,我们想要实现传递两种不同类型的参数,就要进行方法的重载
使用泛型就可以根据参数类型的不同,转换方法的泛型的类型
泛型集合
-
概念:参数化类型、类型安全的集合,强制集合元素的类型必须一致
-
特点:
-
编译时即可检查,而非运行时抛出异常
-
访问时,不必类型转换
-
不同泛型之间引用不能相互赋值,泛型不存在多态
-
-
简单来说,就是我们往集合中添加的各种类型元素都会被存成Object类型,当我们想要去遍历这个集合时,需要把它们强制类型转换为它们原来的类型,这个时候就需要去判断,每一个元素之前是什么类型
-
如果我们使用泛型集合,相当于提前规定了我们可以往集合中放什么类型的数据,放其他类型的数据就会报错,最后遍历集合的时候,也不需要强制类型转换
不使用泛型集合:
package com.generic;
import java.util.ArrayList;
public class Demo01 {
public static void main(String[] args) {
ArrayList arrayList = new ArrayList();
arrayList.add("xxxx");
arrayList.add("aaaa");
arrayList.add(100);
arrayList.add(200);
for (Object o:
arrayList) {
String str = (String) o;
System.out.println(str);
}
}
}
类型转换异常,不能把Integer转换成String
使用泛型集合:
package com.generic;
import java.util.ArrayList;
public class Demo01 {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList();
arrayList.add("aaaaa");
arrayList.add("bbbbb");
//arrayList.add(100); 不能添加非String类型的数据
}
}
for(String str:arrayList){
System.out.println(str);
}