Java泛型2—泛型的使用及擦除

来源:互联网 发布:4g网络哪家好 2016 编辑:程序博客网 时间:2024/05/16 16:06

【作者:孟祥月  博客:http://blog.csdn.net/mengxiangyue】

泛型使用方法很简单,我们在定义一个类的时候在类的名字后面加上“<T>”这样就可以了,然后在实例化该类的时候使用如下格式:类名  变量名<希望存储的数据类型>=new <希望存储的数据类型>();这里使用“<>”来表明这个对象中应该存储的数据类型。以后在我们取得该实例中的参数的时候,就不用在转型了,程序会自动帮我们转型的。

所谓泛型的擦除就是在我们创建该类的实例的时候没有加上希望存储的数据类型,就像其他普通类实例化一样,那样这个类将会把所有的都变成Object。下面先看一段修改后的代码然后再解释,大家会更容易理解:

class Point<T>{private T x;private T y;public T getX(){return x;}public void setX(T x){this.x = x;}public T getY(){return y;}public void setY(T y){this.y = y;}}public class Demo2{public static void main(String[] args){Point<Integer> p = new Point<Integer>();p.setX(2);p.setY(3);int x = p.getX();int y = p.getY();System.out.println("X的坐标是"+x);System.out.println("Y的坐标是"+y);//以下注释的是擦除泛型/*Point p = new Point(); p.setX(2);p.setY(3);int x = (Integer)p.getX();int y = (Integer)p.getY();System.out.println("X的坐标是"+x);System.out.println("Y的坐标是"+y);*/Point pt = new Point();pt.setX(2.3f);//Float f = pt.getX();//这句话将会报错因为擦除泛型后,返回的是Object对象必须进行向下转型System.out.println(pt.getX());System.out.println(new Object());
System.out.println(pt);System.out.println(pt.getX().getClass());}}
在上面程序中Point类的类名后面加上了<T>,类中的所有Object都变成了T(与上篇文章中的程序比较),这里的T指的是我们创建该类的实例的时候需要在外部传递一个确定的类型。在Demo2中我们创建的p对象,约束只能输入Integer类型的数据,在后面我们取得数据的时候,并没有转型也能正确执行。这里没有测试输入其他数据,读者可以自己测试,程序将会报错。

在后面的注释中式擦除泛型,这样我们所存储的xy又都是Object类的了,取得的时候还是需要转型了,看到这里读者应该大概明白了。

下面说一件我认为有意思的事,就是程序的后面几行代码,后面几行程序执行的结果如下:

2.3java.lang.Object@a981cademo2.Point@8814e9class java.lang.Float
读者看到我们使用System.out.println()输出x的时候并没有向下转型但是还是输出了,可能会迷惑,先留着。接着往下看,pt的类型是Point,pt.getX()在内存中的实际字节码是Float,我们就会想pt.getX()返回的是Float对象,我们在使用上面我注释的赋值的时候,为什么还会报告错误,说不能将Object类型的赋值给Float类型的。

这里我们先说一件事,Float是Object的子类,根据面向对象的多态性,虽然实际存储的就是Float类型的,但是对外显示的还是Object类型的数据,所以我们不可以赋值。但是对于输出的时候,因为Float类型覆写了Object类的toSting方法,所以能够正常输出。这里写的不是太好,希望读者能够明白。

class A{void display(){System.out.println("我是A");}}public class B extends A{void display(){System.out.println("我是B");}void show(){System.out.println("这是B的show方法");}public static void main(String[] args){A a = new A();a.display();a = new B();a.display();//a.show();//虽然实际类型是B了但是这时候a只能看见//在A中存在的方法,如果在B中重写了display方法将执//行重写以后的,否则执行A中的。此时的a是看不见B中的show方法的。//B b = a;//这时候虽然a中存储的实际是B但是对外看见的只能是A所以这里必须转型才可以赋值B b = new B();b.show();}}//我是A我是B这是B的show方法
希望我上面说哦这些读者能够明白,本人Java学的也不好,只能解释到这里了,如果哪里写错了,请指出。



原创粉丝点击