(一)关于java泛型的学习总结(泛型方法、泛型擦除)

时间:2023-12-19 15:47:50

目录概要

一、泛型方法

二、利用泛型方法的特性实现代码的简化

三、 关于泛型的擦除

四、*通配符和原生类型区别

五、转型和警告

 

泛型

一般的类中的属性或方法的参数,只能使用具体的类型:要么是基本类型,要么是自定义的类。如果要编写试用于多种类型的代码,这种限制对代码的束缚就会很大。

Java SE5后引入了泛型的概念。泛型实现了参数化类型的概念,当我们使用类或者方法时,可以像普通的函数传参一样传递类型,Java就会自动帮我们类型转换,使得类中可以适用任意类型。

注:基本类型不能作为类型参数

一、泛型方法

基本指导原则:无论何时,比起类声明泛型,我们应该尽量使用泛型方法。如果泛型方法可取代将整个类泛型化,那么就应该只使用泛型方法,因为它可以使事情更清楚明白。对于一个static方法而言,无法访问泛型类的类型参数(静态方法独立于类),所以,如果static方法需要使用泛型,必须使其成为泛型方法。

泛型方法定义示例:

(一)关于java泛型的学习总结(泛型方法、泛型擦除)

运行结果:

(一)关于java泛型的学习总结(泛型方法、泛型擦除)

在此示例中,GenericMethods并不是参数化的,只有方法f()拥有类型参数。

当使用泛型类时,必须在创建对象的时候就指定类型参数的值,而使用泛型方法的时候,通常不必指明参数类型,因为编译器会为我们找出具体的类型。这称为类型判断。因此我们可以向调用普通方法一样调用f(),好像f()被无限次重载过。它甚至可以接受GenericMethods作为其类型参数。

如果调用f()时传入的是基本类型,自动打包机制就会自动将基本类型包装成对应的对象。

二、利用泛型方法的特性实现代码的简化

在正常情况下如果我们要创建一个持有List的Map,要像下面一样:

(一)关于java泛型的学习总结(泛型方法、泛型擦除)

我们重复的使用了类型声明,很显然这是不好的。现在,我们可以利用泛型方法的自动检测类型的特性来简化我们的工作。

我们可以创建一个工具类,他包含各种static方法,专门来创建各种常用的容器对象:

(一)关于java泛型的学习总结(泛型方法、泛型擦除)

现在我们使用工具类创建来和之前的代码比较一下:

(一)关于java泛型的学习总结(泛型方法、泛型擦除)

是不是感觉代码清晰了不少?

不过这只是一个例子,在正常情况下,这个方法的使用还是要视情况而定:如果某人阅读了以上代码,他可能还需要分析工具类New,以及New所隐含的功能,这时就需要权衡。但是不得不说这一特性在某些场景还是很有用的。

三、关于泛型的擦除

在我们定义完泛型后,当编译器对代码编译时,会将我们定义的泛型替换成某种已经存在的类型。具体规则就是擦除到第一个边界:

泛型参数将擦除到第一个边界。如果没有指明,就是Object。

例如: List<?>   编译器将擦除为 List<Object>

List<? extends Student> 编译器将擦除为 List<Student>

四、*通配符和原生类型区别

*通配符Map<String,?>和原生类型Map有时候是不同的,使用*通配符可以增加一个信息:我想用Java泛型来编写这段代码,而不是原生类型,但是当前情况,泛型参数可以持有任何类型。

例如: Map<String ,?> map1=new HashMap();.//会产生警告,没有指定泛型

Map map2=new HashMap();//不会参数警告

五、转型和警告

当使用readObject对对象转型时,可以使用JDK5中的新的转型形式,通过泛型类转型

例如:

LIst<Student> w1`=List.class.cast(in.readObject());

//不能用下面的方式

List<Studetn>w2=List<Student>.class.cast(in.readObject());