美文网首页
Java递归泛型的用法

Java递归泛型的用法

作者: 前度天下 | 来源:发表于2021-04-19 10:54 被阅读0次

java泛型机制有一种奇葩的使用方式,示例代码如下

abstract class Animal<T extends Animal<T>>{
  
}

咋一看,一脸懵逼,仔细一看, 把自己绕了进去,这代码什么意思?

事实上这段代码要在具体的应用场景下才能搞清楚意义

我们来扩展一下刚才那个类,并实现两个类来继承他

abstract class Animal<T extends Animal<T>>{
    private String name;

    public Animal(String name) {
        this.name = name;
    }

    abstract void mating(T t);

    public String toString() {
        return this.name;
    }
}

class Dog extends Animal<Dog> {
    public Dog(String name) {
        super(name);
    }

    @Override
    void mating(Dog dog) {
        System.out.println(this + "和" + dog + "生小狗");
    }
}

class Cat extends  Animal<Cat> {

    public Cat(String name) {
        super(name);
    }

    @Override
    void mating(Cat cat) {
        System.out.println(this + "和" + cat + "生小猫");
    }
}

Dog和Cat继承自 Animal,继承语法如下

class Dog extends Animal<Dog>

class Cat extends Animal<Cat>

然后我们再来匹配一下这个泛型模式

abstract class Animal<T extends Animal<T>>

是不是契合在一起了?

Dog extends Animal<Dog>

对应的不就是

<T extends Animal<T>>

这么做有什么好处呢?以上面的代码为例

Dog类和Cat实现了父类Animal的抽象方法mating

abstract void mating(T t);

这个方法的意思是交配,狗和猫都有交配能力,没毛病

有意思的是,狗显然只能和狗交配,猫只能和猫交配,如果按照传统继承模式,抽象方法的实现

abstract void mating(Animal t)

只能接受表示动物的父类,这显然有问题,如果我们调用Dog的mating方法,传入一个Animal 的实现Cat对象,那么程序将出现BUG,狗和猫显然不能交配,因为有生殖隔离。

而以这种方法实现,就可以避免这种问题,dog的mating只能接受Dog类型参数,cat也一样

        Dog dog1 = new Dog("dog1");
        Dog dog2 = new Dog("dog2");
        Cat cat1 = new Cat("cat1");
        Cat cat2 = new Cat("cat2");

        dog1.mating(dog2);//通过编译
        cat1.mating(cat2);//通过编译
        dog1.mating(cat1);//编译出错
        dog2.mating(cat2);//编译出错
这就可以避免掉某些时候运行期间类型判断,比如

    void mating(Animal dog) {
        if(dog instanceof Dog) {
            System.out.println(this + "和" + dog + "生小狗");
        } else {
            System.out.println("参数传递错误");
        }
    }

类型安全检查在编译期间就完成了。

jdk系统库中,也有用到这种泛型特性,比如Enum类型,他的定义是这样的

public abstract class Enum<E extends Enum<E>>

对于枚举,我们通常这样定义

enum Animals{
    Dog,Cat,Pig
}

实际上这只是一种语法糖,java编译器会将这个枚举编译成一个继承至Enum类的子类

Dog,Cat,Pig分别是Animals的实例,这些枚举对象上的某些方法比如compare只能接受Animals类型的;或者getDeclaringClass方法,返回Class<Animals>,而不是任何Enum类型的子类,这样能最直观方便的保证类型的安全性。

相关文章

  • Java递归泛型的用法

    java泛型机制有一种奇葩的使用方式,示例代码如下 咋一看,一脸懵逼,仔细一看, 把自己绕了进去,这代码什么意思?...

  • 我的Kotlin 学习之路(七)Kotlin之泛型、泛型约束、协

    一、泛型及泛型约束 kotlin中的泛型,和java中思维大体是相同的,但又有些区别 用法和java没什么两样。。...

  • Java泛型基础(一)

    本文首发于个人网站:Java中的泛型(一) 本文主要介绍Java泛型的基本知识,包括目的、泛型类的基本用法和场景应...

  • Java自学-泛型 通配符

    Java 泛型通配符 ? extends super 的用法 示例 1 : ? extends ArrayList...

  • Java泛型教程

    Java泛型教程导航 Java 泛型概述 Java泛型环境设置 Java泛型通用类 Java泛型类型参数命名约定 ...

  • kotlin 泛型

    一:泛型用法 二:泛型约束

  • 泛型 & 注解 & Log4J日志组件

    掌握的知识 : 基本用法、泛型擦除、泛型类/泛型方法/泛型接口、泛型关键字、反射泛型(案例) 泛型 概述 : 泛型...

  • java 泛型

    [Java 泛型总结(一):基本用法与类型擦除] https://segmentfault.com/a/11900...

  • Kotlin 泛型

    说起 kotlin 的泛型,就离不开 java 的泛型,首先来看下 java 的泛型,当然比较熟悉 java 泛型...

  • 第二十八课:泛型

    泛型出现之前 泛型出现之后 Java深度历险(五)——Java泛型

网友评论

      本文标题:Java递归泛型的用法

      本文链接:https://www.haomeiwen.com/subject/hghilltx.html