package com.sample.client;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Test;
/**
* java 之泛型
* 泛型是JDK1.5+的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类,
* 接口,方法的创建中,分别称之为泛型类、泛型接口、泛型方法。
* 简概:泛型只是编译时的概念,供编译器进行语法检查使用的(编程时需要一种类型安全的集合),以此提高程序的可读性和稳定性。
* 目的:
* 1、努力将运行时异常转换成编译时错误,减少运行时异常数量(提高了编译器能力)
* 2、决解模板编程的问题
* 基本语法:属性中使用集合时,用<>指定集合中可以放入的类型。
* 以ArrayList<E>为例:<>表示为typeof
* ArrayList<E>中的E称为类型参数变量
* ArrayList<Integer>中的Integer称为实际类型参数
* 整个称为ArrayList<E>泛型类型
* 整个ArrayList<Integer>称为参数化的类型ParameterizedType
* 注意:
* 1、泛型是提供给javac编译器使用的,它用于限定集合的输入类型,让编译器在源代码级别上,即可挡住翔集合中插入非法数据。
* 但编译器编译完所有泛型的java程序后,生成class文件中将不再带有泛型信息,以此使程序运行效率不受到影响,这个过程称之为"擦除"。
* 2、属性中使用集合时不指定泛型,默认为<Object>
* 3、泛型不同的引用于对象之间都是不兼容的
* 4、引用的泛型于对象的泛型必须一致
*
* @author Administrator
*
*/
public class TestGenerics {
@Test public void testGenerics1() {
List<String> l = new ArrayList<String>();
l.add("ABC");
l.add("DEF");
String str = l.get(0);//使用泛型后,获得对象时不用引进强制类型转换
/*
* 编译错误,试图将Integer和Double类型的对象放入指定存放String类型对象的集合中
* l.add(1);
* l.add(1.5);
*/
}
/**
* 泛型的通配符(用于方法的参数)
* 1、<?> 允许所有泛型的引用调用
* 2、<? extends Number> 只允许泛型为Number以及Number子类的引用调用
* 3、<? super Number> 只允许泛型为Number以及Number父类引用调用
* 4、<? extends Comparable> 只允许泛型为实现Comparable接口的实现类引用调用
*
*/
@Test public void testGenerics2() {
List<String> l1 = new ArrayList<String>();
List<Object> l2 = new ArrayList<Object>();
List<Number> l3 = new ArrayList<Number>();
List<Integer> l4 = new ArrayList<Integer>();
List<Double> l5 = new ArrayList<Double>();
print1(l1);//可调用l1、l2、l3、l4、l5
print2(l2);//可调用l1、l2、l3、l4、l5
print3(l3);//可调用l3、l4、l5
print4(l4);//可调用l1、l3、l4、l5
print5(l3);//可调用l1、l3
}
//方法参数中使用集合时不指定泛型,默认为<?>
public static void print1(List list) {
for(Object o : list) {
System.out.println(o);
}
}
//<?> 允许所有泛型的引用调用
public static void print2(List<?> list) {
for(Object o : list) {
System.out.println(o);
}
}
//<? extends Number> 只允许泛型为Number及Number子类引用调用
public static void print3(List<? extends Number> list){
for(Number o:list){
System.out.println(o);
}
}
//<? extends Comparable> 只允许泛型为实现了Comparable接口的实现类引用调用
public static void print4(List<? extends Comparable> list){
for(Comparable o:list){
System.out.println(o);
}
}
//<? super Number> 只允许泛型为Number及Number父类引用调用
public static void print5(List<? super Number> list){
for(Object o:list){
System.out.println(o);
}
}
/*方法参数中<? extends Number&Comparable>这种修饰符是不支持的
public static void print6(List<? extends Number & Comparable> list){
for(Object o:list){
System.out.println(o);
}
}
*/
/**
* 泛型的通配符(用于泛型方法)
* 定义:修饰符 泛型 返回类型 方法名 参数列表 抛出的异常
* 语法:<T>、T可以是任意字母,但通常必须要大写(常用字母T)。<T>通常需放在方法的返回值声明之前。
* 1、<T> 允许所有泛型的引用调用
* 2、<T extends Number> 只允许泛型为Number及Number类型的子类引用调用
* 3、<T extends Comparable> 只允许泛型为实现了Comparable接口的实现类的引用调用
* 4、<T extends Number&Comparable>只允许泛型为既是Number及Number子类 又实现了Comparable接口的实现类的引用调用
*
* 注意:
* 泛型方法中<? super Number>这种修饰符是不支持的
*
*/
@Test public void TestGenerics3(){
List<String> l1 = new ArrayList<String>();
List<Object> l2 = new ArrayList<Object>();
List<Number> l3 = new ArrayList<Number>();
List<Integer> l4 = new ArrayList<Integer>();
List<Double> l5 = new ArrayList<Double>();
String[] a1 = new String[10];
Object[] a2 = new Object[10];
Number[] a3 = new Number[10];
Integer[] a4 = new Integer[10];
Double[] a5 = new Double[10];
copyFromArray(l1,a1);
copyFromArray(l2,a2);
copyFromArray(l3,a3);
copyFromArray(l4,a4);
copyFromArray(l5,a5);
}
public static<T> void copyFromArray(List<T> l,T[] a){
for(T o : a){
l.add(o);
}
}
// <T extends Number> 只允许泛型为Number及Number子类的引用调用
public static <T extends Number > void copyFromArray1(List<T> l,T[] a){
for(T o:a){
l.add(o);
}
}
/* 此处不许用super
*
public static <T super Number> void copyFromArray2(List<T> l,T[] a){
for(T o:a){
l.add(o);
}
}
*/
}
/**
* 注意: 只有对象类型才能作为泛型方法的实际参数
* 在泛型中可以同时有多个类型,
*/