原例: 使用泛型后:
public class GenTest{ public class GenTest{
public static void main(String[] args){ public static void main(String[] args){
GenString gs = new GenString(); GenObj<String> gs = new Genobj<String>();
gs.setName("zhangsan"); gs.setValue("zhangsan");
GenValue gv = new GenValue(); System.out.println(gs);
gv.setValue(120.0); GenObj<Double> gv = new GenObj<Double>();
} gv.setValue(120.0);
} System.out.println(gv);
class GenString{ }
String name; }
public String getName(){ class GenObj<T>{
return name; T value;
} public T getValue(){
public void setName(String name){ return value;
this.name = name; }
} public void setValue(T v){
} value = v;
class GenDouble{ }
Double value; public String toString(){
public Double getValue(){ return "GenObj=[" + value +"]";
return value; }
} }
public void setValue(double v){
value = v;
}
}
通过上面的例子我们可以看出使用泛型以后,代码在外观上有了明显的改变。但是在运行和结果上是没发生改变的。使用泛型后把class GenString和class GenDouble这两个结构相同的类简化成一个类,使得代码有所简化。所以对于泛型,我们可以理解为在类的声明是时通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型,泛型能够解决数据类型的安全性问题。在以往的J2SE中,没有泛型的情况下,通常是使用Object类型来进行多种类型数据的操作。这个时候操作最多的就是针对该Object进行数据的强制转换,而这种转换是基于开发者对该数据类型明确的情况下进行的(比如将Object型转换为String型)。倘若类型不一致,编译器在编译过程中不会报错,但在运行时会出错。使用泛型的好处在于,它在编译的时候进行类型安全检查,并且在运行时所有的转换都是强制的,隐式的,大大提高了代码的重用率。然而泛型不是随便可以乱用的,使用泛型也是有一定的规则和限制,使用泛型的规则和限制,如下:
1、泛型的参数类型只能是类(class)类型,而不能是简单类型。 比如,<int>是不可使用的。
2、可以声明多个泛型参数类型,比如<T, P,Q…>,同时还可以嵌套泛型,例如:<List<String>>
3、泛型的参数类型可以使用extends语句,例如<T extends superclass>。
4、泛型的参数类型可以使用super语句,例如< T super childclass>。
5、泛型还可以使用通配符,例如<? extends ArrayList>
然而在我们使用泛型以后,代码的变化会使我们产生一定的疑惑,有时候甚至会出现读不懂、说不清楚的情况,因为使用泛型后会产生很多类似于修饰的成分。比如:
public static <T extends Object & Comparable<? super T>> T main(Collection<? extends T>?coll);
一看到这个例子我刚开始也懵了,各个部分是能懂的。但是总起来就是不会说。后来才明白我们可以通过一步一步的简化来读它,那样这个泛型句子就没那么难懂了。下面来看看它的简化步骤:
首先,去掉所有泛型表示后,它就会变成:public static Object main(Collection coll);
其次,分步加入泛型修饰:public static T main(Collection<T> coll);然后增加对T的修饰:public static <T extends Object & Comparable> T main(Collection<T> coll);
最后,进一步的对T的修饰进行完善和方法参数的修饰:public static <T extends Object & Comparable<? super T>> T main(Collection<? extends T> coll);