泛型
泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)
泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。
泛型类
语法:类名
T表示类型占位符,表示一种引用类型,如果编写多个,使用逗号隔开。
创建泛型类:
public class MyGeneric<T> {}
使用泛型:
package Generic;
//泛型类
//语法:类名<T>
//T表示类型占位符,表示一种引用类型,如果编写多个,使用逗号隔开。
public class MyGeneric<T> {
//使用泛型T
// 1.创建变量
T t;
// 2.作为方法的参数
public void show(T t) {
//不能实例化,即不能new
System.out.println(t);
}
// 3.泛型作为方法的返回值
public T getT() {
return t;
}
}
测试泛型类:
package Generic;
public class TestGeneric {
public static void main(String[] args) {
// 注意:
// 1.泛型只能使用引用类型
// 2.不同泛型对象之间不能互相复制
// 使用泛型类创建字符串对象
MyGeneric<String> gen1=new MyGeneric<String>();
gen1.t="hello";
gen1.show("加油!");
String str=gen1.getT();
// 使用泛型类创建数字对象
MyGeneric<Integer> gen2=new MyGeneric<Integer>();
gen2.t=12;
gen2.show(45);
Integer in=gen2.getT();
}
}
泛型接口
语法:接口名
注意:不能创建泛型静态常量
创建泛型接口:
package Generic;
//泛型接口
//语法:接口名<T>
//不能创建泛型静态常量
public interface MyInterface<T> {
String name="uzi";
//在没有使用泛型接口之前并不知道类型,所以不能用new
T server(T t);
}
接口不能实例化,所以要创建一个接口实现类:
package Generic;
public class MyInterfaceImpl1 implements MyInterface<String>{
// 在传递类型的时候确定类型为String
@Override
public String server(String s) {
System.out.println(s);
return s;
}
}
这里的MyInterfaceImpl1在实现MyInterface接口的时候,传递的类型确定类型为String。也可以不规定类型,接口实现类代码:
package Generic;
public class MyInterfaceImpl2<T> implements MyInterface<T>{
// 在传类型的时候不确定
@Override
public T server(T t) {
System.out.println(t);
return t;
}
}
测试泛型接口:
package Generic;
public class TestGeneric {
public static void main(String[] args) {
// 测试泛型接口
MyInterfaceImpl1 impl1=new MyInterfaceImpl1();
impl1.server("ming");
MyInterfaceImpl2 impl2=new MyInterfaceImpl2();
impl2.server(1000);
impl2.server("uzi");
}
}
imlp1由于在实现接口类中规定了类型,所以必须是String,而impl2没有规定类型,即可以创建不同类型。
泛型方法
语法: 返回值类型
创建泛型方法:
package Generic;
//泛型方法
//语法:<T> 返回值类型
public class MyGenericMethod {
// 创建泛型方法
public <T> void show(T t){
System.out.println("泛型方法"+t);//无返回值
}
public <T> T show2(T t){
System.out.println("泛型方法"+t);//有返回值
return t;
}
}
测试泛型方法:
package Generic;
public class TestGeneric {
public static void main(String[] args) {
// 测试泛型方法
MyGenericMethod myGenericMethod=new MyGenericMethod();
myGenericMethod.show("你好啊");//不需要规定类型
myGenericMethod.show(3.14);
myGenericMethod.show2(123);//类型由传递的数据决定
}
}
泛型集合
即泛型在集合中的使用
泛型集合测试代码:
package Generic;
import java.util.ArrayList;
import java.util.Iterator;
public class MyArrayList {
public static void main(String[] args) {
/* ArrayList arrayList=new ArrayList();
arrayList.add("uzi");
arrayList.add(22);
arrayList.add("ming");
arrayList.add(23);//可以向集合中添加任何类型的数据
for (Object o : arrayList) {
String str=(String) o;
System.out.println(str);
}//报错,因为类型不同有String类型也有int类型*/
// 使用泛型避免异常
ArrayList<String> arrayList=new ArrayList<String>();
arrayList.add("uzi");
// arrayList.add(22);//报错,只能添加String类型的
arrayList.add("ming");
ArrayList<Student> arrayList1=new ArrayList<Student>();
Student s1 = new Student("uzi", 23);
Student s2 = new Student("ming", 24);
arrayList1.add(s1);
arrayList1.add(s2);
arrayList1.add(new Student("doinb",26))
// arrayList1.add("1451");
//遍利
Iterator<Student> it = arrayList1.iterator();
while (it.hasNext()){
Student s=it.next();//拿到的类型就是Student,而不是Object,不要需要再进行强制类型转换
System.out.println(s.toString());
}
}
}
其中Student类代码:
package Generic;
public class Student {
public String name;
public int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}