JAVA使用泛型改进Object参数类型统一带来的缺陷 Myth丶恋晨 2023-07-03 14:30 76阅读 0赞 泛型是在jdk1.5之后被引入的,技术革新一定是由于前面的技术的缺陷造成的,因此需要了解泛型出现的原因,才能更好的理解和使用泛型。 ## 一:多态性复习 ## 在之前已经写了一篇关于java多态性的理解总结,链接如下: [JAVA多态性][JAVA] 为节约篇幅,接下来就接上一篇继续进行。 class Ball{ public void play(){ System.out.println("在玩Ball"); } } class BasketBall extends Ball{ public void rule(){ System.out.println("篮球规则为:....... "); } public void play(){ System.out.println("在玩篮球"); } } class FootBall extends Ball{ public void play(){ System.out.println("在玩足球"); } } public class DemoTest{ public static void main(String args[]){ Ball ball = new BasketBall();//向上类型转换 playRule(ball); } public static void playRule(Ball ball){ BasketBall bb = (BasketBall)ball; //向下类型转换(强制转换) bb.rule(); } } 拿了一段代码,上面定义static静态方法时参数的类型为Ball,是父类,实际上传输的是BasketBall这个子类对象,实现了参数统一,具体的作用优点已经在上面的链接文章中给出了。 ## 二:Object的超然地位 ## 在jdk1.9之后,java引入了自动装箱和自动拆箱机制,这就给基本数据类型转换成相应的引用数据类型提供了便利。而Object类是又是所有类的父类,他可以接收所有的引用类型。即可以实现将所有的引用类型实例对象转换成Object的对象(向上类型转换)。也就可以实现参数的统一,比上面的还要彻底 ! Object ball = new BasketBall();//向上类型转换 ## 三:由Object引发的问题 ## 成也萧何败也萧何,由于Object的描述范围的广泛,也会造成一些安全隐患 class Ball{ //... } class BasketBall extends Ball{ public void rule(){ System.out.println("篮球规则为:....... "); } } class FootBall extends Ball{ public void rule(){ System.out.println("足球规则为:....... "); } } public class MulChangeUpTest{ public static void main(String args[]){ Ball ball = new BasketBall(); playRule(ball); } public static void playRule(Object obj){ FootBall b = (FootBall)obj; b.rule(); } } **运行结果:编译成功,运行报错** ![在这里插入图片描述][20200207123534775.png] 让人头疼的是:**这个问题他是编译不报错的,而是运行时报错的,这就会造成极大的安全隐患**。 有人说为什么不去使用`instanceof` 去判断一下,-\_- 可千万不要抬杠,我们这是在提出问题,准备去解决问题。但是`instanceof`只是一个防治措施,**是为了防止出现崩溃,并不是解决问题的根本措施,治标不治本**。 ## 四:泛型出场 ## 我们在了解到了由于Object作为参数带来的缺点之后,必须要进行解决。我特别喜欢老师说的一句话,**转型会带来问题那么就不去转型**。使用别的途径去解决问题。 class Ball<T>{ // 球的类型可能使用String,或者Integer类型代表 private T ballType; public void setBallType(T ballType){ this.ballType = ballType; } public T getBallType(){ return this.ballType; } } public class DemoTest{ public static void main(String args[]){ Ball<Integer> ball = new Ball<Integer>(); ball.setBallType(10); int type = ball.getBallType(); System.out.println(b.getBallType()); } } 当前**类型被死死的限制为了Integer**,就不会造成这种安全隐患了。 此时编译和运行都正确。使用泛型`<T>`来表示Type类型,**这个Ball类内部的所有T代表的类型,是在运行时动态决定的。** 如果不按照泛型定义的类型进行赋值: public class DemoTest{ public static void main(String args[]){ Ball<Integer> ball = new Ball<Integer>(); ball.setBallType("篮球"); } } 报错信息: ![在这里插入图片描述][20200207133358664.png] 如此,使用了泛型后在编译期间就会报错,就将这种安全隐患解决了。 ## 五:参数统一下的泛型:泛型通配符 ## 先看一段代码 class Ball<T>{ // 球的类型可能使用String,或者Integer类型代表 private T ballType; public void setBallType(T ballType){ this.ballType = ballType; } public T getBallType(){ return this.ballType; } } public class DemoTest{ public static void main(String args[]){ Ball<Integer> ball = new Ball<Integer>(); ball.setBallType(10); playRule(ball); } public static void playRule(Ball<String> b){ System.out.println(b.getBallType()); } } 先想一想,我们使用Object的最大优点是什么? 就是实现了参数类型的统一。但是使用了上面的泛型来定义playRule的参数类型时,将传入的参数类型限制在了String类型。Integer类型的就会报错,这与我们改善Object的初衷是相悖的。 此时就需要一个泛型用于描述一切的类型。即泛型通配符 ## <?> ## public static void playRule(Ball<?> b){ System.out.println(b.getBallType()); } ## 六:总结 ## 技术改进的道理如果明白,那么在使用时自然就更会印象深刻,接受更快。在理解他的设计思想和改进原因下,更会事半功倍。 [JAVA]: https://blog.csdn.net/sun_DongLiang/article/details/104168036 [20200207123534775.png]: https://img-blog.csdnimg.cn/20200207123534775.png [20200207133358664.png]: https://img-blog.csdnimg.cn/20200207133358664.png
相关 Java泛型使用不当带来的类型安全问题 在Java中,泛型(Generics)是一种强大的工具,用于创建能够处理多种数据类型的类。然而,如果不正确地使用泛型,可能会导致以下类型安全问题: 1. 类型擦除:虽然声明了 待我称王封你为后i/ 2024年10月19日 23:24/ 0 赞/ 31 阅读
相关 Java泛型:类型擦除带来的问题案例 在Java编程中,泛型是一种强大的工具,它允许我们在编写代码时,不指定具体的类或数据类型。然而,当类型擦除(Type Erasure)发生时,我们可能会遇到一些问题。 1. 迷南。/ 2024年10月14日 02:09/ 0 赞/ 43 阅读
相关 Java泛型编程带来的类型安全问题 Java泛型编程是一种编程模式,它允许我们在编写代码时指定容器(如数组、列表或集合)的元素类型。通过这种方式,编译器可以在运行时检查元素类型是否符合预期,从而实现类型安全。 ╰+攻爆jí腚メ/ 2024年09月26日 18:18/ 0 赞/ 59 阅读
相关 Java泛型:如何避免类型转换带来的问题? 在Java中,泛型是一种允许你在创建类或接口时指定类型的方法。然而,尽管泛型提供了强大的类型安全,但过度依赖强制类型转换可能会引发问题。 以下是一些避免类型转换问题的建议: 女爷i/ 2024年09月24日 17:12/ 0 赞/ 62 阅读
相关 Java泛型中类型参数的安全使用 在Java的泛型编程中,类型参数的安全使用主要是避免类型擦除、多态性问题以及类型安全检查。 1. 避免类型擦除:在非静态方法或构造函数中,如果类型参数被擦除,可能会导致运行时 浅浅的花香味﹌/ 2024年09月20日 19:06/ 0 赞/ 54 阅读
相关 Java泛型使用:如何避免类型转换带来的问题? 在Java中,泛型是一种允许你在类、接口或方法中定义类型参数。类型参数在编译时是无形的,但在运行时需要进行类型转换。 为了避免类型转换带来的问题,可以采取以下策略: 1. 偏执的太偏执、/ 2024年09月20日 01:09/ 0 赞/ 62 阅读
相关 Java泛型:如何避免类型转换带来的问题 在Java中,泛型是一种强大的工具,可以让我们编写更加灵活和安全的代码。然而,由于类型擦除(Type Erasure)的特性,有时我们可能会遇到类型转换带来的问题。 以下是一 野性酷女/ 2024年09月16日 23:12/ 0 赞/ 61 阅读
相关 Java泛型使用不当带来的问题:类型擦除示例 在Java中,泛型是为了解决类型安全问题的一种机制。然而,如果使用不当,也会带来一些问题,特别是类型擦除的问题。 类型擦除是指编译器在运行时将泛型转换为具体类型的操作。这通常 小灰灰/ 2024年09月11日 08:30/ 0 赞/ 48 阅读
相关 JAVA使用泛型改进Object参数类型统一带来的缺陷 泛型是在jdk1.5之后被引入的,技术革新一定是由于前面的技术的缺陷造成的,因此需要了解泛型出现的原因,才能更好的理解和使用泛型。 一:多态性复习 在之前已经写了一篇关 Myth丶恋晨/ 2023年07月03日 14:30/ 0 赞/ 77 阅读
还没有评论,来说两句吧...