• 自定义泛型


    本次博客带领大家学习自定义泛型,了解自定义泛型类、接口和方法等等。

    自定义泛型类

    • 基本语法
    class 类名<T,R...>{//...表示可以有多个泛型
        成员
    }
    
    • 1
    • 2
    • 3
    • 注意细节
      1. 普通成员可以使用泛型(属性、方法)。
      2. 使用泛型的数组,不能初始化。
      3. 静态方法中不能使用类的泛型。
      4. 泛型类的类型,是在创建对象时确定的(因为创建对象时,需要指定确定类型)。
      5. 如果在创建对象时,没有指定类型,默认为Object。
    class Tiger<T,R,M>{
        String name;
        R r;
        M m;
        T t;
        //因为数组在new 不能确定T的类型,就无法在内存开空间
        T[] ys ;
    
        public Tiger(String name, R r, M m, T t) { //构造器使用泛型
            this.name = name;
            this.r = r;
            this.m = m;
            this.t = t;
        }
        
        //因为静态是和类相关的,在类加载加载时,对象还没有创建
        //所有,如果静态方法和静态属性使用了泛型,JVM就无法完成初始化
        static R r2;
        public static void m1(M m){
            
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public R getR() {
            return r;
        }
    
        public void setR(R r) { //方法使用到泛型
            this.r = r;
        }
    
        public M getM() {
            return m;
        }
    
        public void setM(M m) {
            this.m = m;
        }
    
        public T getT() {
            return t;
        }
    
        public void setT(T t) {
            this.t = t;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    //T=Double,R=String ,M=Integer
    Tiger<Double, String, Integer> g = new Tiger<>("john");
    g.setT(10.9);//OK
    //g.setT("yy");//错误,类型不对
    System.out.println(g);
    Tiger g2  = new Tiger("john~~~");//OK  T=Object R=Object M=Object
    g2.setT("yy");//OK,因为T=Object "yy"=String 是Object子类。
    System.out.println("g2="+g2);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    自定义泛型接口

    • 基本语法:
    interface 接口名<T,R...>{
    }
    
    • 1
    • 2
    • 注意细节
      1. 接口中,静态成员也不能使用泛型(这个和泛型类规定一样)。
      2. 泛型接口的类型,在继承接口或者实现接口时确定。
      3. 没有指定类型,默认为Object。
    //在继承接口 指定泛型接口的类型
    interface IA extends IUsb<String,Double>{
    
    }
    //当我们去实现IA接口时,因为IA在继承IUsb 接口时,指定了U 为String R为Double
    //在实现IUsb接口的方法时,使用String替换U,Double 替换R
    class AA implements IA{
    
        @Override
        public Double get(String s) {
            return null;
        }
    
        @Override
        public void hi(Double aDouble) {
    
        }
    
        @Override
        public void run(Double r1, Double r2, String u1, String u2) {
    
        }
    }
    
    //实现接口时,直接指定泛型接口的类型
    //给U指定Integer 给R指定了Float
    //所以,当我们实现IUsb方法时,会使用Integer替换 U, Float替换R
    class BB implements IUsb<Integer,Float>{
    
        @Override
        public Float get(Integer integer) {
            return null;
        }
    
        @Override
        public void hi(Float aFloat) {
    
        }
    
        @Override
        public void run(Float r1, Float r2, Integer u1, Integer u2) {
    
        }
    }
    
    //没有指定类型,默认为Object。
    //建议直接写成class CC implements IUsb
    class CC implements IUsb{//等价于class CC implements IUsb
        @Override
        public Object get(Object o) {
            return null;
        }
    
        @Override
        public void hi(Object o) {
    
        }
    
        @Override
        public void run(Object r1, Object r2, Object u1, Object u2) {
    
        }
    
    }
    
    interface IUsb<U,R>{
    
        int n = 10;
       // U name; 接口中的属性是静态属性
    
        //普通方法中,可以使用接口泛型
        R get(U u);
    
        void hi(R r);
    
        void run(R r1,R r2,U u1,U u2);
    
        //在jdk8中,可以在接口中,使用默认方法
        default R method(U u){
            return null;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82

    自定义泛型方法

    • 基本语法
    修饰符 <T,R...>返回类型 方法名(参数列表){
    }
    
    • 1
    • 2
    • 注意细节
      1. 泛型方法,可以定义在普通类中,也可以定义在泛型类中。
      2. 当泛型方法被调用时,类型会确定。
      3. public void eat(E e){},修饰符后没有 eat方法不是泛型方法,而是使用了泛型。
    public class CustomMethodGeneric {
        public static void main(String[] args) {
            Car car = new Car();
            car.fly("宝马",100);//当调用方法时,传入参数,编译器,就会确定类型。
            System.out.println("=======");
            car.fly(300,100.1);
    
            //T -->String R--->ArrayList
            Fish<String, ArrayList> fish = new Fish<>();
            fish.hello(new ArrayList(),11.1);
        }
    }
    //泛型方法,可以定义在普通类中,也可以定义在泛型类中。
    class Car{ //普通类
        public void run(){ //普通方法
    
        }
        //说明 泛型方法
        //1. 这个就是泛型
        //2.是提供给 fly使用的
        public<T,R> void fly(T t,R r){//泛型方法
            System.out.println(t.getClass());
            System.out.println(r.getClass());
        }
    }
    
    class Fish<T,R>{ //泛型类
        public void run(){ //普通方法
        }
        public<U,M> void eat(U u,M m){//泛型方法
    
        }
        //1.下面hi方法不是泛型方法。
        //2.是hi方法使用了类声明的泛型
        public void hi(T t){
        }
        //泛型方法,可以使用类声明的泛型,也可以使用自己声明泛型
        public<K> void hello(R r,K k){
            System.out.println(r.getClass());
            System.out.println(k.getClass());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    自定义泛型练习

    • 下面代码是否正确,如果有错误,修改正确,并说明输出什么?
    class Apple<T,R,M>{
        public<E> void fly(E e){
            System.out.println(e.getClass().getSimpleName());
        }
        public void eat(U u){}
        public void run(M m){}
    }
    class Dog{}
    
    //下面代码输出什么?
    Apple<String,Integer,Double> apple = new Apple<>();
    apple.fly(10);
    apple.fly(new Dog());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    public class CustomMethodGenericExercise {
        public static void main(String[] args) {
            Apple<String,Integer,Double> apple = new Apple<>();
            apple.fly(10);//10 会被自动装箱 Integer10,输出Integer
            apple.fly(new Dog());//Dog
        }
    }
    class Apple<T,R,M>{//自定义泛型类
        public<E> void fly(E e){//泛型方法
            System.out.println(e.getClass().getSimpleName());
        }
        //public void eat(U u){}//错误,因为U没有声明
        public void run(M m){}//ok
    }
    class Dog{}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
  • 相关阅读:
    Python asyncore模块-客户端
    ElasticSearch常见面试题汇总
    Java核心技术卷Ⅰ-第四章对象和类
    Ceph介绍与部署
    获取当前OA地址JSP处理判断逻辑
    学会 Python yield 关键词,此文就够了
    使用机器学习创建自己的Emojis 表情
    python获取某电商平台口红数据并制作词云
    分布式链路追踪Jaeger + 微服务Pig在Rainbond上的实践分享
    字节码进阶之java反射的底层实现原理
  • 原文地址:https://blog.csdn.net/lidong777777/article/details/126119010