> 文档中心 > 《Java 核心技术 卷1》 笔记 第12章 泛型程序设计(7)泛型类型的继承限定

《Java 核心技术 卷1》 笔记 第12章 泛型程序设计(7)泛型类型的继承限定


 

 12.7 泛型类型的继承规则

下面一段程序展示了父子泛型对应的类互相赋值的过程。猜一猜1、2这两句哪句是正确的呢?还是都不正确?

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

public class Main {    public static  void main(String[] args) { Main solution = new Main(); Son a = new Son(); Son b = new Son(); Pair ancient = new Pair(a,b); Pair inheritor = new Pair(a,b); ancient = inheritor;//1 inheritor = ancient;//2    }}class Parent{ }class Son extends Parent{ }class Pair{    T first;    T second;    public Pair(T first,T second){ this.first = first; this.second = second;    }}

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

结果(都不正确):

🚗🚓🚕🛺🚙🚌🚐🚎🚑🚒🚚🚛🚜🚘🚔🚖🚍🦽🦼🛹🚲🛴🛵🏍

🚗🚓🚕🛺🚙🚌🚐🚎🚑🚒🚚🚛🚜🚘🚔🚖🚍🦽🦼🛹🚲🛴🛵🏍

原因分析:泛型类型无论是否父子类,相同类给予的不同泛型间都不可以相互赋值,否则违背了泛型的初衷----类型检查

如果一定要进行赋值呢?我们前面提到过两个重要的点:

📕 泛型是用于辅助编译器检查的,不使用泛型只要保证程序正确是可以运行的

📗 使用泛型的变量,赋值给不使用泛型的变量会产生警告(本步骤无法检查泛型)

所以我们可以在中间这一步,不使用泛型,以回避父子类问题,如下:

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

public class Main {    public static  void main(String[] args) { Main solution = new Main(); Son a = new Son(); Son b = new Son(); Pair ancient = new Pair(a,b); Pair inheritor = new Pair(a,b);// Pair center = inheritor;//1// ancient = center; Pair center2 = ancient;//2 inheritor = center2; System.out.println(inheritor.toString()); System.out.println(ancient.toString());    }}class Parent{ }class Son extends Parent{ }class Pair{    T first;    T second;    public Pair(T first,T second){ this.first = first; this.second = second;    }@Override    public String toString() { return "Pair{" +  "first=" + first +  ", second=" + second +  '}';    }}

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

运行结果:

🚗🚓🚕🛺🚙🚌🚐🚎🚑🚒🚚🚛🚜🚘🚔🚖🚍🦽🦼🛹🚲🛴🛵🏍

🚗🚓🚕🛺🚙🚌🚐🚎🚑🚒🚚🚛🚜🚘🚔🚖🚍🦽🦼🛹🚲🛴🛵🏍

这样是可以运行的,解决了报错问题。

然后会产生警告。于是我们发现泛型的类型检查约束在赋值的这两步转换中,失效了。我们无法确定赋值这个操作是安全的,也无法保证进行赋值的两个变量的泛型间,具有父子关系。

怎么能既完成类型检查,又不让泛型产生报错呢?

 12.8 通配符类型

 12.8.1 通配符的类型限定

 1)子类限定

子类类型赋值给父类类型,如下:

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

public class Main {    public static  void main(String[] args) { Main solution = new Main(); Son a = new Son(); Son b = new Son(); Pair ancient = new Pair(a,b); Pair inheritor = new Pair(a,b);// Pair center = inheritor;//1// ancient = center; Pair center2 = ancient;//2 inheritor = center2; System.out.println(inheritor.toString()); System.out.println(ancient.toString());    }}class Parent{ }class Son extends Parent{ }class Pair{    T first;    T second;    public Pair(T first,T second){ this.first = first; this.second = second;    }@Override    public String toString() { return "Pair{" +  "first=" + first +  ", second=" + second +  '}';    }}

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

 2)父类限定

同样的,如果需要把父类类型赋值给子类类型,可使用 super,如下:

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

public class Main {    public static  void main(String[] args) { Main solution = new Main(); Parent a = new Parent(); Parent b = new Parent();Son c = new Son(); Son d = new Son(); Pair ancient = new Pair(a,b); Pair inheritor = new Pair(c,d); inheritor = ancient;    }}class Parent{ }class Son extends Parent{ }class Pair{    T first;    T second;    public Pair(T first,T second){ this.first = first; this.second = second;    }@Override    public String toString() { return "Pair{" +  "first=" + first +  ", second=" + second +  '}';    }}

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

总结:

1. 子类赋值给父类,使用 限定泛型

2. 父类赋值给子类,使用 限定泛型

相关内容:选择 《Java核心技术 卷1》查找相关笔记

评论🌹点赞👍收藏✨关注👀,是送给作者最好的礼物,愿我们共同学习,一起进步

如果对作者发布的内容感兴趣,可点击下方关注公众号 钰娘娘知识汇总 查看更多作者文章哦!