认识泛型
-
定义类,接口,方法时,同时声明了一个或者多个类型变量(如:<E>)
称为泛型类,泛型接口,泛型方法,他们统称为泛型。
public class ArrayList<E>{ ..... }
-
作用:泛型提供了在编译阶段约束所能操作的数据类型,并自动进行检查的能力!
这样可以避免强制类型转换,及其可能出现的异常。
package YMP.genericity; import java.util.ArrayList; public class GenericDemo01 { public static void main(String[] args) { //目标:认识泛型,搞清楚泛型的好处 ArrayList<String> list=new ArrayList<String>(); list.add("java"); list.add("php"); /*list.add(23); list.add(99.9); list.add(true); list.add('a'); list.add(new Object());*/ //获得数据 for(int i=0;i<list.size();i++){ /*Object rs=list.get(i); //把数据类型进行转型 String s=(String) rs;*/ String s=list.get(i); System.out.println(s); } } }
-
泛型的本质:把具体的数据类型作为参数传给类型变量。
泛型类
修饰符 class 类名 <类型变量,类型变量,...>{ }
-
注意:类型变量建议用大写的英文字母,常用的有:E,T,K,V等。
package YMP.genericity; public class GenericDemo02 { public static void main(String[] args) { //目标:学会自定义泛型类 //需求:请您模拟ArrayList集合自定义一个集合MyArrayList MyArrayList<String> mylist=new MyArrayList<>();//JDK1.7 之后,后面的类型可以省略 mylist.add("hello"); mylist.add("world"); // mylist.add(555); mylist.add("java"); mylist.add("前端"); System.out.println(mylist.remove("world")); System.out.println(mylist); } }
package YMP.genericity; import java.util.ArrayList; //泛型类 public class MyArrayList<E> { private ArrayList list=new ArrayList(); public boolean add(E e){ list.add(e); return true; } public boolean remove(E e){ return list.remove(e); } @Override public String toString() { return list.toString(); } }
泛型接口
修饰符 interface 接口名<类型变量,类型变量,...>{ }
-
注意:类型变量建议用大写的英文字母,常用的有:E,T,K,V等。
package YMP.genericity.Demo03Generic; public class GenericDemo03 { public static void main(String[] args) { //目标:搞清楚泛型接口的基本作用 //需求:项目需要对学生老师数据都要进行增删改查操作 StudentData studentData=new StudentData(); studentData.add(new Student()); studentData.delete(new Student()); Student s=studentData.query(1); } }
package YMP.genericity.Demo03Generic; public class Student { } package YMP.genericity.Demo03Generic; public class Teacher { }
package YMP.genericity.Demo03Generic; public interface Data <T>{ void add(T t); void delete(T t); void update(T t); T query(int id); }
package YMP.genericity.Demo03Generic; public class StudentData implements Data<Student>{ @Override public void add(Student student) { } @Override public void delete(Student student) { } @Override public void update(Student student) { } @Override public Student query(int id) { return null; } } package YMP.genericity.Demo03Generic; public class TeacherData implements Data<Teacher>{ @Override public void add(Teacher teacher) { } @Override public void delete(Teacher teacher) { } @Override public void update(Teacher teacher) { } @Override public Teacher query(int id) { return null; } }
泛型方法,通配符,上下限
泛型方法
修饰符<类型变量,类型变量,...>返回值类型 方法名(形参列表){ }
package YMP.genericity.Demo04Generic; import YMP.genericity.Demo03Generic.Student; public class GenericDemo04 { public static void main(String[] args) { //目标:学会定义泛型方法,搞清楚作用 //需求:打印任意数组的内容 String[] names={"张三","李四","王五"}; printArray(names); Student[] stus=new Student[3]; printArray(stus); Student max=getMax(stus); String max2=getMax(names); } public static <T> void printArray(T[] names){ } public static <T> T getMax(T[] names){ return null; } }
通配符
-
就是 “?” ,可以在“使用泛型”的时候代表一切类型;E T K V 是在定义泛型的时候使用。
泛型的上下限
-
泛型上限:?extends Car:?能接收的必须是Car或者其子类。
-
泛型下限:?super Car:?能接收的必须是Car或者其父类。
package YMP.genericity.Demo04Generic; import java.util.ArrayList; public class GenericDemo05 { public static void main(String[] args) { //目标:理解通配符和上下限 ArrayList<Xiaomi> xiaomis=new ArrayList<>(); xiaomis.add(new Xiaomi()); xiaomis.add(new Xiaomi()); xiaomis.add(new Xiaomi()); go(xiaomis); ArrayList<BYD> byds=new ArrayList<>(); byds.add(new BYD()); byds.add(new BYD()); byds.add(new BYD()); go(byds); /* ArrayList<Dog> dogs=new ArrayList<>(); dogs.add(new Dog()); dogs.add(new Dog()); dogs.add(new Dog()); go(dogs);*/ } //需求:开发一个极品飞车的游戏 //虽然Xiaomi和BYD是Car的子类,但是ArrayList<Xiaomi> ArrayList<BYD> 和 ArrayList<Car>没有半毛钱光系! //**泛型的上下限** // //* 泛型上限:?extends Car:?能接收的必须是Car或者其子类。 //* 泛型下限:?super Car:?能接收的必须是Car或者其父类。 public static void go(ArrayList<?extends Car> cars){ } }
package YMP.genericity.Demo04Generic; public class Xiaomi extends Car{ } package YMP.genericity.Demo04Generic; public class LX extends Car{ } package YMP.genericity.Demo04Generic; public class BYD extends Car{ } package YMP.genericity.Demo04Generic; public class Dog { }
泛型支持的类型
-
泛型不支持基本数据类型,只能支持对象数据类型(引用数据类型)。
包装类
-
包装类就是把基本类型的数据包装成对象的类型
自动装箱:基本数据类型可以自动转换为包装类型。
自动拆箱:包装类型可以自动转换为基本数据类型。
package YMP.genericity.Demo05Generic; import java.util.ArrayList; public class GenericDemo06 { public static void main(String[] args) { //目标:泛型和集合都不支持基本数据类型(引用数据类型) /*ArrayList<int> list=new ArrayList<>();*/ //泛型擦除:泛型工作在编译阶段,等编译后泛型就没用了,所以泛型在编译后就会被擦除。 //所有类型会回复为Object,Object是对象类型只能指向对象,不能接基本数据类型 //把基本数据类型包装类对象 //手工包装 //Integer i=new Integer(100);//过时 Integer it1=Integer.valueOf(100);//推荐 Integer it2=Integer.valueOf(100);//推荐 System.out.println(it1==it2);//true Integer it3=Integer.valueOf(130); Integer it4=Integer.valueOf(130); System.out.println(it3==it4);//false //Integer中已经封装了-128~127的数字,所以it1和it2指向的是同一地址 //而it3和it4已经超出127,所以指向的不是同一地址 //自动装修:基本数据类型可以直接变成包装对象的数据,不需要额外做任何事情 Integer it11=100; Integer it22=100; System.out.println(it11==it22);//true Integer it33=130; Integer it44=130; System.out.println(it33==it44);//false //自动拆箱:把包装类的对象直接给基本数据类型 int i=it11; System.out.println(i); ArrayList<Integer> list=new ArrayList<>(); list.add(130);//自动装箱 list.add(120); int rs=list.get(1);//自动拆箱 System.out.println("----------------------------------"); //包装类新增的的功能 //1.把基本类型的数据转换为字符串 int j=23; String rs1=Integer.toString(j);//"23" System.out.println(rs1+1);//231 Integer i2=j; String rs2=i2.toString();//"23" System.out.println(rs2+1);//231 String rs3=j+""; System.out.println(rs3+1);//231 System.out.println("----------------------------------"); //把字符串数值转换为对应的基本数据类型 String str="98"; //int i1=Integer.parseInt(str); int i1=Integer.valueOf(str); System.out.println(i1+2); String str2="98.8"; double d=Double.valueOf(str2); System.out.println(d+2); } }
包装类具备的其他功能
-
可以把基本类型的数据转化为字符串类型。
public static String toString(double d) public String toString()
-
可以把字符串类型的数值转换为数值本身对应的真实数据类型。
public static int parsenInt(String s) public static Integer valueOf(String s)