目录概要
一、泛型方法
二、利用泛型方法的特性实现代码的简化
三、 关于泛型的擦除
四、*通配符和原生类型区别
五、转型和警告
泛型
一般的类中的属性或方法的参数,只能使用具体的类型:要么是基本类型,要么是自定义的类。如果要编写试用于多种类型的代码,这种限制对代码的束缚就会很大。
Java SE5后引入了泛型的概念。泛型实现了参数化类型的概念,当我们使用类或者方法时,可以像普通的函数传参一样传递类型,Java就会自动帮我们类型转换,使得类中可以适用任意类型。
注:基本类型不能作为类型参数
一、泛型方法
基本指导原则:无论何时,比起类声明泛型,我们应该尽量使用泛型方法。如果泛型方法可取代将整个类泛型化,那么就应该只使用泛型方法,因为它可以使事情更清楚明白。对于一个static方法而言,无法访问泛型类的类型参数(静态方法独立于类),所以,如果static方法需要使用泛型,必须使其成为泛型方法。
泛型方法定义示例:
运行结果:
在此示例中,GenericMethods并不是参数化的,只有方法f()拥有类型参数。
当使用泛型类时,必须在创建对象的时候就指定类型参数的值,而使用泛型方法的时候,通常不必指明参数类型,因为编译器会为我们找出具体的类型。这称为类型判断。因此我们可以向调用普通方法一样调用f(),好像f()被无限次重载过。它甚至可以接受GenericMethods作为其类型参数。
如果调用f()时传入的是基本类型,自动打包机制就会自动将基本类型包装成对应的对象。
二、利用泛型方法的特性实现代码的简化
在正常情况下如果我们要创建一个持有List的Map,要像下面一样:
我们重复的使用了类型声明,很显然这是不好的。现在,我们可以利用泛型方法的自动检测类型的特性来简化我们的工作。
我们可以创建一个工具类,他包含各种static方法,专门来创建各种常用的容器对象:
现在我们使用工具类创建来和之前的代码比较一下:
是不是感觉代码清晰了不少?
不过这只是一个例子,在正常情况下,这个方法的使用还是要视情况而定:如果某人阅读了以上代码,他可能还需要分析工具类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());