`
bigBan
  • 浏览: 6705 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

java泛型

阅读更多
java泛型
一、简介:
jdk1.5新推出的概念,c++中叫做STL
 
ClassCastException 类型转换异常,泛型多是解决这些问题。
使用泛型后,编译时候不会出问题,结束时候也不会出现问题。
 
package com.liuyao.generic;
 
classBooleanFool{
privateBoolean foo;
 
publicBoolean getFoo(){
return foo;
}
 
publicvoid setFoo(Boolean foo){
this.foo = foo;
}
}
 
classIntegerFool{
privateInteger foo;
 
publicInteger getFoo(){
return foo;
}
 
publicvoid setFoo(Integer foo){
this.foo = foo;
}
}
 
publicclassIntegerFoo{
 
/**
* @param args
*/
publicstaticvoid main(String[] args){
// TODO Auto-generated method stub
 
}
}
为Booleanhe Integer分别创建了两个不同的fool对象,很不方便也不效率。
 
改进型:
package com.liuyao.generic;
 
 
publicclassObjectFoo{
privateObject foo;
 
publicObject getFoo(){
return foo;
}
 
publicvoid setFoo(Object foo){
this.foo = foo;
}
 
publicstaticvoid main(String[] args){
ObjectFoo foo1 =newObjectFoo();
ObjectFoo foo2 =newObjectFoo();
foo1.setFoo(newBoolean(true));
foo2.setFoo(newInteger(3));
 
Boolean boolean1 =(Boolean)foo1.getFoo();
Integer i =(Integer)foo2.getFoo();
 
String string =(String)foo2.getFoo();
}
}
在使用时候,仍然会产生一些问题,如String在使用时候,编译时候没有错误,但是在运行时候,便会输出:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String at com.liuyao.generic.ObjectFoo.main(ObjectFoo.java:25)
 
所以这样的改进仍然会产生问题 ,为了终极改进,引入泛型机制:
代码:
package com.liuyao.generic;
 
//T代表的是类型的信息,
 
publicclassGenericFoo<T>{
private T fooT;
 
public T getFooT(){
return fooT;
}
 
publicvoid setFooT(T fooT){
this.fooT = fooT;
}
 
/**
* @param args
*/
publicstaticvoid main(String[] args){
// TODO Auto-generated method stub
GenericFoo<String> sFoo =newGenericFoo<String>();
sFoo.setFooT("hello");
// 注意在,这个时候便会产生编译器错误,把运行时错误改进到了编译时期
Integer integer = sFoo.getFooT();
}
}
这里的T还可以使用A、B、C等等(一般一个大写字母即可);

这个时候编译器都会提示该传递什么类型的参数。
 
泛型的定义:泛型是程序设计语言的一种特性。允许程序员在强类型程序设计语言中编写代码时定义一些可变部分,那些部分在使用前必须作出指明。各种程序设计语言和其编译器、运行环境对泛型的支持均不一样。将类型参数化以达到代码复用提高软件开发工作效率的一种数据类型。泛型类是引用类型,是堆对象,主要是引入了类型参数这个概念。
 
二、java泛型语法
可以用到泛型的地方(语法定义):
    1、泛型接口:interface Interface<T>{}
    2、泛型类:public class GenericFoo<T>
    3:泛型方法:public <T> T run(T l){ return l; };
注:在泛型方法与泛型接口内部,泛型参数的类型信息被擦除了,所以在泛型信息内部不能进行其方法的调用,但是在泛型方法中,可以通过传递进来的参数,用getClass方法来获取其运行时信息。例如:
package com.liuyao.generic;
//T代表的是类型的信息,
 
class Interface{
    @SuppressWarnings("unchecked")
    public <T> T run(T l){ 
        Class<? extends Object> classtypeClass = l.getClass();
        String nameString = classtypeClass.getName();
        return (T) nameString;
        }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Interface in = new Interface();
        System.out.println(in.run(""));
        System.out.println(in.run(3));
        System.out.println(in.run(new Integer(4)));
    }
}
output:

泛型方法的特点:
    1、在方法的内部就可以知道程序在运行时的运行时信息。
    2、泛型方法本身是与类独立的泛型,无论类是否使用泛型,方法本身的泛型不受影响。
    3、static方法无法访问类的泛型参数,如果想让static方法是用泛型,在必须成为泛型方法。
    4、泛型方法在使用时候不需要向泛型类那样制定泛型参数类型(类型参数判断),编译器为我们找出具体的类型。
 
例子:一个通用的对象生成器。
package com.liuyao.generic;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
classGenetor<T>implementsIterator<T>{
privateClass<T> classType;    //hnzhongyao
publicGenetor(Class<T> classType){
super();
this.classType = classType;
}
publicboolean hasNext(){
returnfalse;
}
public T next(){
T l=null;
try{
l = classType.newInstance();
}catch(InstantiationException e){
e.printStackTrace();
}catch(IllegalAccessException e){
e.printStackTrace();
}
return l;
}
publicvoid remove(){
}
}
publicclassGenrators<T>{
 
publicstatic<T>Collection<T> fill(Collection<T> coll,Genetor<T> gen,int n){
for(int i =0;i<n;i++){
coll.add(gen.next());
}
return coll;
}
publicstaticvoid main(String[] args){
Collection<String> l = fill(newArrayList<String>(),newGenetor<String>(String.class),10);
System.out.println(l.size());
Iterator<String> iterator = l.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
三、泛型的擦除
从一个小例子看透泛型的擦除:
package com.liuyao.generic;
 
import java.util.ArrayList;
 
public class EraseInfo {
 
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Class<?> info1 = new ArrayList<String>().getClass();
        Class<?> info2 = new ArrayList<Integer>().getClass();
        System.out.println(info1.equals(info2));
    }
}
输出:

结论:
    ArrayList<String> 与 ArrayList<Integer>()具有同样的Class对象,Class对象用于描述所有该类在运行时的信息,由于该;两个类具有相同的Class对象,则这两个类的运行时信息完全相同,所以后面的制定的泛型参数的类型信息完全消失了,也就是被擦除了。(Java编程思想第四版)。
总结:泛型擦除的特点:
    1、在泛型代码内部,无法获得任何有关泛型参数类型的信息。
    2、无发创建对象。
    3、提供了边界的泛型参数,可以提供一定的信息类型边界信息。
 
由于泛型的擦除特性,我们必须协助泛型,给定泛型的边界,以此告知编译器只能接受遵循这个边界的类型。
例如:
package com.liuyao.generic;
classPet{
publicvoid bark(){
System.out.println("bark");
};
}
classDogextendsPet{
publicvoid run(){
System.out.println("run");
}
}
publicclassEraseInfo2<T extendsPet>{
T obj;
 
publicEraseInfo2(T obj){
super();
this.obj = obj;
}
//通过指定了边界,可以调用以这个为边界所允许的方法
publicvoid doIt(){
obj.bark();
}
publicstaticvoid main(String[] args){
Dog dog =newDog();
EraseInfo2<Dog> dogl =newEraseInfo2<Dog>(dog);
dogl.doIt();
}
}
泛型擦除的代价:
    1、泛型不能运用于运行时类型的操作之中。 如instanceof 和 new关键字的操作。
    2、在泛型类上不提供任何的泛型参数也不会出现任何错误。
    3、不同泛型参数的统一泛型对象,其Class对象完全相同,会产生混淆。
 
四、边界
泛型的边界可以使得参数类型附加限定条件。
作用:
    1、可以安装自己的边界类型来进行方法调用。
    2、可以配合通配符使用。
分享到:
评论

相关推荐

    java泛型总结

    深入理解java泛型,包括类名泛型的定义,方法泛型定义,泛型的返回

    Java泛型定义与用法实例详解

    主要介绍了Java泛型定义与用法,结合实例形式较为详细的分析了Java中泛型的概念、原理、定义、使用方法及相关操作注意事项,需要的朋友可以参考下

    Java泛型的简单实例

    介绍了Java泛型的简单实例,有需要的朋友可以参考一下

    详谈Java泛型中T和问号(通配符)的区别

    下面小编就为大家带来一篇详谈Java泛型中T和问号(通配符)的区别。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    Java泛型变量如何添加约束

    主要介绍了Java泛型变量如何添加约束,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    Java泛型单元试题.html

    精选java关于泛型的原理,应用和面试题,包含所有泛型考点。例如,泛型的概念,类型,实例化,容易混淆的用法。每一道题附上答案,方便理解考试要点。

    java 泛型

    NULL 博文链接:https://wuzq1223.iteye.com/blog/1564295

    Java泛型的用法及T.class的获取过程解析

    主要介绍了Java泛型的用法及T.class的获取过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    Java泛型(一)

    今天学习Java泛型技术,这个在平时里用的也很多但在我在工作中用到深处的可能并不是很多,定义泛型类也很少用到的基本就是用到集合中写泛型。但是作为学习还是要多学一些基本理论性的东西,对比较深的东西理解起来...

    Java 泛型全解析

    主要介绍了Java 泛型的相关资料,帮助大家更好的理解和学习Java,感兴趣的朋友可以了解下

Global site tag (gtag.js) - Google Analytics