认识泛型
-
定义类,接口,方法时,同时声明了一个或者多个类型变量(如:<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)