泛型
泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)
泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。
泛型类
语法:类名
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 + '}'; } }