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)

小结

相关推荐
qq_441996051 小时前
Mybatis官方生成器使用示例
java·mybatis
巨大八爪鱼1 小时前
XP系统下用mod_jk 1.2.40整合apache2.2.16和tomcat 6.0.29,让apache可以同时访问php和jsp页面
java·tomcat·apache·mod_jk
码上一元3 小时前
SpringBoot自动装配原理解析
java·spring boot·后端
计算机-秋大田3 小时前
基于微信小程序的养老院管理系统的设计与实现,LW+源码+讲解
java·spring boot·微信小程序·小程序·vue
魔道不误砍柴功5 小时前
简单叙述 Spring Boot 启动过程
java·数据库·spring boot
失落的香蕉5 小时前
C语言串讲-2之指针和结构体
java·c语言·开发语言
枫叶_v5 小时前
【SpringBoot】22 Txt、Csv文件的读取和写入
java·spring boot·后端
wclass-zhengge5 小时前
SpringCloud篇(配置中心 - Nacos)
java·spring·spring cloud
路在脚下@5 小时前
Springboot 的Servlet Web 应用、响应式 Web 应用(Reactive)以及非 Web 应用(None)的特点和适用场景
java·spring boot·servlet
黑马师兄5 小时前
SpringBoot
java·spring