欢迎来真孝善网,为您提供真孝善正能量书籍故事!

深入解析Java泛型及其通配符:应用场景与利弊分析

时间:11-12 神话故事 提交错误

公共无效乐趣(){

ArrayList arr=new ArrayList(); //没有使用泛型定义的集合

arr.add(1);

arr.add("你好");

//编译器无法发现下面的代码是错误的,但是JVM运行时会抛出ClassCastException类型转换异常。

String s=(String)arr.get(0);

s.trim();

}

2. 泛型为什么是语法糖?

Sun引入泛型后,编译器并没有强制要求在使用泛型类时必须明确定义泛型,但会出现黄色警告线。即使使用泛型类显式定义泛型后,编辑器也会执行类型擦除,即JVM 根本不识别泛型!

如果不进行类型擦除,很多JDK1.5之前的代码将无法兼容,所以使用语法糖来保持兼容性,但是对语法糖也带来了许多的弊端。

3.1 语法糖的弊端引入之一(数组与集合进行PK)

数组和集合进行了PK。数组说,我可以使用多态性定义

@测试

公共无效显示(){

对象[] arr=new String[2];

arr[0]="你好";

arr[1]=1; //语法没有问题,编辑没有错误,但是运行时会抛出ArrayStoreException数组错误类型存储异常。

}集合也想用泛型来做到这一点,但是一旦集合允许,JVM就没有办法为接下来的操作list.add(1);抛出异常,因为泛型是语法糖,编译器会执行类型擦除除此之外,JVM 不知道泛型!

所以编译阶段不允许存在这个语法,使用泛型前后必须保持类型一致。@Test

公共无效show2(){

ArrayList列表=新的ArrayList(); //这里编译错误

列表.add("你好")

//列表.add(1);

}

3.2 语法糖的弊端引入之二(形式参数)

以下面代码为例。使用泛型作为形参时,如果传递的参数是new ArrayList(),则相当于ArrayListarr=new ArrayList()。由于使用泛型前后类型必须一致,所以传递的实际参数只能是new ArrayList()。

公共无效方法(ArrayListarr){

}

@测试

公共无效显示(){

ArrayListarr1=new ArrayList();

ArrayListarr2=new ArrayList();

方法(arr1);

method(arr2);//这里编译错误

}

4. 泛型通配符的引入

如果上面的代码还需要传入泛型Number类型呢?让我们先把方法的多功能性放在一边,来想一个解决方案。为什么不尝试方法重载呢?一件非常尴尬的事情发生了。由于泛型是语法糖,因此编译后将执行类型擦除。我们眼中的重载方法简单来说就是一个方法!public void method(ArrayListarr) { //编译错误

}

public void method(ArrayListarr) { //编译错误

}于是,Sun公司的天才们引入了一种新的语法——通用通配符。泛型通配符的出现解决了方法可重用性的问题,特别是当泛型用作形式参数时,但其他本身还存在一些问题。

公共无效方法(ArrayList?arr){

}

5.1 无界泛型通配符弊端

当无界泛型通配符作为形参时,作为调用方,实际传递的参数类型不受限制。然而,在方法内部,泛型类的参数和返回值为泛型的方法,不能使用!泛型类ArrayList仅在创建对象时指定泛型的类型。然而,在method方法中声明的局部变量arr中,指定的泛型是?对应的T get(int index)和boolean add(T t)方法都是T?它是任意类型,因此该方法无效。

公共无效方法(ArrayList?arr){

Stirng s=arr.get(0);//编译错误

arr.add("hello");//编译错误

}

@测试

公共无效显示(){

ArrayListarr1=new ArrayList();

ArrayListarr2=new ArrayList();

方法(arr1);

方法(arr2);

}

5.2 子类限定泛型通配符弊端

//注意:Integer类是final修饰的,不能有子类。以下代码只是一个示例。

为了解决上述问题,出现了另一种语法——子类限定泛型通配符。调用方法时,只能传递其本身或其子类。调用者有一定的限制,但上帝已经关闭了它。一扇门还必须打开另一扇窗~~方法内部,泛型类的返回值为泛型的方法,可以使用了。方法method声明的局部变量arr,指定的泛型是? extends Integer,调用该方法时,ArrayList中的T必须是Integer对象或者Integer对象的子类。

对于T get(int index),返回的是Integer 对象或Integer 对象的子类。使用整数对象进行接收,父类引用指向子类对象。

对于boolean add(T t),要求传入的参数是Integer或者Integer的子类,所以不能传递Integer对象。

公共无效方法(ArrayList?扩展Integerarr){

整数i=arr.get(0);

arr.add(123);//编译错误

}

@测试

公共无效显示(){

ArrayListarr1=new ArrayList();

ArrayListarr2=new ArrayList();

方法(arr1);

method(arr2);//编译错误

}

5.3 父类限定泛型通配符弊端

父类限定通用通配符只能在调用者处传递其自身或其父类。方法内部,泛型类的参数列表为泛型的方法,可以使用了。方法method声明的局部变量arr,指定的泛型是? super Integer,调用该方法时,ArrayList中的T必须是Integer对象或者Integer对象的父类。

对于T get(int index),返回的是Integer对象或者Integer对象的父类,Integer对象不能用于接收。

对于boolean add(T t),要求传入的参数是Integer对象或者Integer对象的父类。如果传入Integer对象,父类引用就指向子类对象,这就是多态的原理。

公共无效方法(ArrayList?超级Integerarr){

Integer i=arr.get(0);//编译错误

arr.add(123);

}

@测试

公共无效显示(){

ArrayListarr1=new ArrayList();

ArrayListarr2=new ArrayList();

方法(arr1);

方法(arr2);

}

6. 总结

当定义泛型类作为方法的形参时,有以下几种情况:

1:只使用泛型,不使用泛型通配符。公共无效添加(ArrayListarr){}

实际参数只能以定义变量的受限数据类型传递。

2:使用无界通用通配符,public void add(ArrayList?arr){}

不能使用参数和返回值都是泛型的泛型方法。

3:使用子类限定通用通配符,public void add(ArrayList? extends Integerarr){}

参数列表为泛型的方法不能在泛型类中使用。

4:使用父类限定泛型通配符,public void add(ArrayList? super Integerarr){}

不能使用返回值为泛型的泛型方法

在定义方法时,需要根据实际情况进行具体分析。

导入java.util.ArrayList;

公开课演示{

Tt;

//对于第一种情况

公共无效show1(ArrayListarr){

}

//对于第二种情况

公共无效show2(ArrayList?arr){

}

//对于第三种情况

公共无效show3(ArrayList?扩展塔尔){

T t=arr.get(0);

}

//针对第四种情况

公共无效show4(ArrayList?超级塔尔){

arr.add(t);

}

好了,文章到这里就结束啦,如果本次分享的深入解析Java泛型及其通配符:应用场景与利弊分析和问题对您有所帮助,还望关注下本站哦!

用户评论

颜洛殇

学习Java,总觉得泛型和泛型通配符这部分有点抽象, 这篇文章正好能解释一下实际应用

    有12位网友表示赞同!

逾期不候

我觉得了解泛型就是为了写更安全、更可维护的代码,通配符也让代码更灵活

    有20位网友表示赞同!

嗯咯

用 Java 来开发时遇到过很多类型错误,感觉泛型和通配符可以帮助解决这个问题!

    有11位网友表示赞同!

熏染

刚接触Java的时候对泛型不太理解,现在看文章里这样详细的分析感觉醍醐灌顶了!

    有14位网友表示赞同!

爱到伤肺i

在团队项目中使用泛型和通配符能让代码更规范,其他人也更容易理解!

    有16位网友表示赞同!

疲倦了

这篇文章写得很好,把泛型的优缺点都总结得很清楚了。

    有19位网友表示赞同!

凉月流沐@

感觉学习泛型有点难度,希望可以多看一些例子来加深理解。

    有19位网友表示赞同!

放血

我一直在找一篇关于泛型和通配符的文章,正好今天看到了!

    有18位网友表示赞同!

掉眼泪

想学习 Java 高级知识,泛型一定要掌握啊,以后要好好跟进这方面的内容。

    有14位网友表示赞同!

〆mè村姑

看来泛型和通配符在实际开发中还是非常有用的工具。

    有8位网友表示赞同!

泡泡龙

Java 的底层机制原来这么强大!

    有6位网友表示赞同!

箜篌引

学习完这个文章感觉对 Java 编程有了更深入的理解...

    有16位网友表示赞同!

青衫故人

以后写的代码一定要尽量使用泛型,可以避免很多类型错误 !

    有15位网友表示赞同!

陌潇潇

通配符的使用场景好像还是挺广泛的

    有13位网友表示赞同!

有一种中毒叫上瘾成咆哮i

感觉泛型的应用要根据实际情况选择,不能一味追求过度复杂化。

    有7位网友表示赞同!

开心的笨小孩

这篇文章很好的总结了泛型的优缺点,非常实用!

    有12位网友表示赞同!

你瞒我瞒

以后在写 Java 代码的时候,一定要注意使用泛型和通配符优化代码效率。

    有12位网友表示赞同!

糖果控

希望作者可以分享更多关于泛型和通配符的案例!

    有6位网友表示赞同!

【深入解析Java泛型及其通配符:应用场景与利弊分析】相关文章:

1.蛤蟆讨媳妇【哈尼族民间故事】

2.米颠拜石

3.王羲之临池学书

4.清代敢于创新的“浓墨宰相”——刘墉

5.“巧取豪夺”的由来--米芾逸事

6.荒唐洁癖 惜砚如身(米芾逸事)

7.拜石为兄--米芾逸事

8.郑板桥轶事十则

9.王献之被公主抢亲后的悲惨人生

10.史上真实张三丰:在棺材中竟神奇复活