Java -泛型

认识泛型

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

小结

相关推荐
麦芽糖02192 分钟前
SSE介绍及使用(Server-Send Events)
java
alan07216 分钟前
【Java + Elasticsearch全量 & 增量同步实战】
java·elasticsearch·jenkins
hashiqimiya19 分钟前
后端springboot的接收前端发来的数据反序列化原理
java
cat三三1 小时前
java之异常
java·开发语言
浙江第二深情1 小时前
前端性能优化终极指南
java·maven
养乐多07221 小时前
【Java】IO流
java
俊男无期1 小时前
超效率工作法
java·前端·数据库
中国胖子风清扬1 小时前
SpringAI和 Langchain4j等 AI 框架之间的差异和开发经验
java·数据库·人工智能·spring boot·spring cloud·ai·langchain
月明长歌1 小时前
【码道初阶】牛客TSINGK110:二叉树遍历(较难)如何根据“扩展先序遍历”构建二叉树?
java·数据结构·算法
用户2190326527352 小时前
Spring Boot + Redis 注解极简教程:5分钟搞定CRUD操作
java·后端