读书人

菜鸟学Java(二十)

发布时间: 2013-10-06 18:25:14 作者: rapoo

初学者学Java(二十)
泛型(Generics)

泛型是作为jdk5.0的新特性出现的,在没有泛型之前,我们使用集合类的时候,不管存的是什么类型,返回的都是Object类型,用的时候需要强制类型转换。但如果我们存的如果是String类型的变量,却强制类型转换为Integer类型,这样在编译的时候并不会报错,因为我们是将一个Object类型的转换为Integer类型,而系统在编译时并不知道我们存如的是String类型,但在执行的时候会出现异常。

为了解决这个问题我们引入了泛型。

泛型的使用方法

1.规定数据类型,提高代码的安全性(以ArrayList为例)

在学泛型以前我们使用ArrayList会产生一个警告。

例:

package test;

import java.util.*;

public class GenericsTestOne {

public static void main(String[]args) {

List listOne = newArrayList();

}

}

警告是这么写的:

ArrayList 是原始类型。应该将对通用类型ArrayList<E> 的引用参数化。

后面的<E>就是泛型的一种表现形式。

他说没有用泛型进行引用参数化,如果不进行参数化会引起什么错误呢。

下面我写这么几行代码:

listOne.add("冶近玮");

Integer int1 =(Integer)listOne.get(0);

这在编译的时候并不会报错,因为集合get()方法返回的是一个Object类型的,在编译的时候编译器并不知道我在内部存放的是一个String类的变量,所以这么写不会报错。但在执行的时候他就会知道内部是String类,所以会给我报一个异常,是这么写的:

java.lang.ClassCastException: java.lang.Stringcannot be cast to java.lang.Integer

也就是说String类型的变量不能转换成Integer类型。

而我们的泛型就是解决这个问题的,如果使用泛型,只要代码在编译时没有出现警告,就不会遇到运行时ClassCastException。下面我们看看泛型怎么使用,和使用后的效果。还是上面这个程序我只修改 一行:

List<String> listOne = new ArrayList<String>();

这时在我们把String强制转换为Integer的那行,他就不会不痛不痒的给个警告,而会直接给出错误:

不能从 String 强制类型转换为Integer。

所以泛型可以提高代码的安全性。

2.泛型可以提高代码的质量

在以前,我们想要写一个类,类中有一个字符串变量,get(),set(),构造方法。还有一个类,类中有一个Integer变量,get(),set(),构造方法。只能这么写:

class MyTestOne

{

private String string1;

public String getString1() {

return string1;

}

public void setString1(String string1) {

this.string1 = string1;

}

public MyTestOne(String string1)

{

this.string1 = string1;

}

}

class MyTestTwo

{

private Integer integer1;

public Integer getString1() {

return integer1;

}

public void setString1(Integer integer1) {

this.integer1 = integer1;

}

public MyTestTwo(Integer integer1)

{

this.integer1= integer1;

}

}

这只是两个类呢,要是20个呢?还不得累死。但是我们学了泛型就可以这么写:

class MyTest<T>

{

private T o1;

public T getString1() {

return o1;

}

public void setString1(T o1) {

this.o1 = o1;

}

public MyTest(To1)

{

this.o1 = o1;

}

}

如果你想要一个String型的你就这么声明:

MyTest<String>myTest1 =new MyTest<String>("冶近玮");

如果你想要一个Integer型的你就这么声明:

MyTest<Integer> myTest2= new MyTest<Integer>(new Integer(1));

效果和上面写两个类效果是一样的,来20个类,不过就是多20个声明罢了,会大大的减少代码量。

而且在定义泛型类别时,预设可以使用任何的类型来实例化泛型类型中的类型,但是如果想要限制使用泛型类别时,只能用某个特定类型或者是其子类型才能实例化该类型时,可以在定义类型时,使用extends关键字指定这个类型必须是继承某个类,或者实现某个接口。其实我们上面写的<T>是等价于下面这个式子。

<T extends Object>

就算两个类名相同的变量,泛型不同也不能互相赋值,如上例的myTest1和myTest2就不能互相赋值,否则报错。

关于泛型我就说这些了。

读书人网 >编程

热点推荐