一、什么是泛型
泛型(泛:广泛)—> 广泛的数据类型
将某一个类/接口/方法/变量的数据类型象使用参数一样传递给类/接口/方法/变量。
数据类型的参数化,任意化
二、为什么需要泛型
假如我们需要写一个程序,但很多业务逻辑相似
第一天 类中的x,y变量需要int类型
package com.wangxing.test1;
public class IntTest {
private int x;
private int y;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
第二天 类中的x,y变量需要double类型,我们创建一个新类修改了一下x,y变量数据类型
package com.wangxing.test1;
public class DoubleTest {
private double x;
private double y;
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
}
第三天 类中的x,y变量需要String ,我们创建一个新类修改了一下x,y变量数据类型
第四天 类中的x,y变量需要char ,我们创建一个新类修改了一下x,y变量数据类型
…
当我们需要多个业务逻辑相似,数据类型不同的java类时,我们又不想创建出多个业务逻辑相似,数据类型不同的java类。
我们就会想能不能用一个类把业务逻辑相似,数据类型不同的多个java类,统一起来。要解决这个统一问题我们就要首先处理数据类型的统一,要处理数据类型的统一,我们会想到java.lang.Object类。
package com.wangxing.test2;
public class ObjectTest {
private Object x;
private Object y;
public Object getX() {
return x;
}
public void setX(Object x) {
this.x = x;
}
public Object getY() {
return y;
}
public void setY(Object y) {
this.y = y;
}
}
测试使用类
package com.wangxing.test2;
public class TestMain1 {
public static void main(String[] args) {
ObjectTest o=new ObjectTest();
//o.setX(180);
//o.setY(36);
//将x,y变量改成String
o.setX("一百八十");
o.setY("三十六");
System.out.println(o.getX()+","+o.getY());
//类型转换
// java.lang.ClassCastException
int sum=(Integer)(o.getX())+(Integer)(o.getY());
System.out.println(sum);
}
}
虽然我们可以使用Object来统一数据类型,但是在使用时需要进行强制类型转换,如果转换不当会出现类型转换异常 java.lang.ClassCastException。
我们需要处理的是在具体操作使用过程中能不能不进行强制类型转换,避免类型转换异常 java.lang.ClassCastException发生。
这时我们就会想能不能把数据类型,像参数一样传递给我们需要使用的java类,这样我们既可以统一类型,又可以避免强制类型转换。
这是泛型被研究出来的缘由,为解决上面的问题。
三、如何创建一个泛型类/泛型接口
package com.wangxing.test3;
public class FanXingLei<T> {
private T x;
private T y;
public T getX() {
return x;
}
public void setX(T x) {
this.x = x;
}
public T getY() {
return y;
}
public void setY(T y) {
this.y = y;
}
}
在创建类的时候为类名后面添加一个“<>”,给”<>”中添加单个的大写字母,用来接收具体的某个数据类型。
”<>”中的单个的大写字母可以出现多个,中间使用”,”分割。
类中需要数据类型的部分可以使用单个的大写字母来代替,这时我们创建类的时候就可以传递具体的数据类型给单个的大写字母,类中需要数据类型的部分全部都会变成我们传递具体的数据类型。
四、泛型类/泛型接口如何使用
使用泛型类:
-
使用泛型类创建对象的时候需要传递具体的数据类型。
例如:FanXingLei fanx1=new FanXingLei();
FanXingLei fanx2=new FanXingLei(); -
基本数据类型在被作为泛型的数据类型时,是不被允许的,可以适应基本类型对应的封装类型代替
例如:FanXingLei fanx3=new FanXingLei(); //错误的
FanXingLei fanx4=new FanXingLei(); -
当我们创建泛型对象的时候,没有传递指定的数据类型默认是Object类型。并伴随有警告信息出现。
例如:FanXingLei fanx5=new FanXingLei();
fanx5.setX(Object);
package com.wangxing.test3;
public class TestMain1 {
public static void main(String[] args) {
FanXingLei<Integer> fanx1=new FanXingLei<Integer>();
fanx1.setX(180);
fanx1.setY(36);
//fanx1.setX("一百八十");
//fanx1.setY("三十六");
System.out.println(fanx1.getX()+","+fanx1.getY());
int sum= fanx1.getX()+fanx1.getY();
System.out.println(sum);
FanXingLei<String> fanx2=new FanXingLei<String>();
fanx2.setX("一百八十");
fanx2.setY("三十六");
System.out.println(fanx2.getX()+","+fanx2.getY());
//基本数据类型在被作为泛型的数据类型时,是不被允许的,可以适应基本类型对应的封装类型代替
//FanXingLei<double> fanx3=new FanXingLei<double>(); //错误
FanXingLei<Double> fanx4=new FanXingLei<Double>();
//当我们创建泛型对象的时候,没有传递指定的数据类型默认是Object类型。并伴随有警告信息出现。
FanXingLei fanx5=new FanXingLei();
//fanx5.setX(Object);
}
}
之前学习过的类,他们其实是泛型类
java.util Class ArrayList
ArrayList(Collection<? extends E> c)
java.util Class HashMap<K,V>
java.util Class Hashtable<K,V>
之前学习过的接口,他其实是泛型接口
java.util Interface Map<K,V>
public interface List
public interface Collection
例如:
package com.wangxing.test4;
public class Student {
private int stuid;
private String stuname;
private int stuage;
private String stuaddress;
public Student() {}
public Student(int stuid,String stuname,int stuage,String stuaddress) {
this.stuid=stuid;
this.stuname=stuname;
this.stuage=stuage;
this.stuaddress=stuaddress;
}
public int getStuid() {
return stuid;
}
public void setStuid(int stuid) {
this.stuid = stuid;
}
public String getStuname() {
return stuname;
}
public void setStuname(String stuname) {
this.stuname = stuname;
}
public int getStuage() {
return stuage;
}
public void setStuage(int stuage) {
this.stuage = stuage;
}
public String getStuaddress() {
return stuaddress;
}
public void setStuaddress(String stuaddress) {
this.stuaddress = stuaddress;
}
}
package com.wangxing.test4;
import java.util.ArrayList;
import java.util.List;
public class TestMain1 {
public static void main(String[] args) {
Student stu1=new Student(1001,"zhangsan",23,"西安");
Student stu2=new Student(1002,"lisi",24,"beijing");
Student stu3=new Student(1003,"wangwu",25,"上海");
ArrayList stulist1=new ArrayList();
stulist1.add(stu1);
stulist1.add(stu2);
stulist1.add(stu3);
//遍历stulist1集合
for(Object obj:stulist1) {
//强制类型转换
Student stu=(Student)obj;
System.out.println(stu.getStuid()+","+
stu.getStuname()+","+
stu.getStuage()+","+
stu.getStuaddress());
}
List<Student> stulist2=new ArrayList<Student>();
stulist2.add(stu1);
stulist2.add(stu2);
stulist2.add(stu3);
//遍历stulist2集合
for(Student stu:stulist2) {
System.out.println(stu.getStuid()+","+
stu.getStuname()+","+
stu.getStuage()+","+
stu.getStuaddress());
}
}
}
运行结果