泛型入门

/**
 * 第三十六集 入门泛型的基本应用
 * 体验泛型
 * jdk1.5以前的集合类中存在的问题
 * ArrayList collection = new ArrayList();
 * collection.add(1);
 * collection.add(1L);
 * collection.add("abc");
 * int i = (Integer)collection.get(1);
 * 有一个集合增加了整数,一个长整数,一个字符串
 * jdk1.5的集合类希望你在定义集合时,明确表示你要向集合中装
 * 哪种类型的数据,无法加入指定类型以外的数据
 * 泛型是提供给Javac编译器使用的,可以限定集合中的输入类型,
 * 让编译器挡住源程序中的非法输入,编译器编译带类型说明的集合时
 * 会去掉”类型“信息,使程序运行效率不受影响,对于参数化的泛型类型,
 * getClass()的返回值和原类型完全一样。由于编译生成的字节码会
 * 去掉泛型类型信息,只要能跳过编译器,就可以往某个泛型集合中加入
 * 其它类型的数据,例如,用反射得到集合,再调用其add方法即可
 * 

 */

基本概念

泛型是JDK1.5的新特性内容之一,由于内容较多较杂,不易掌握,单独笔记。泛型就是一般的所有类型。应用在JDK1.5的安全机制,将运行时期的问题ClassCastException转到了编译时期。避免了强制转换的麻烦。当操作的引用数据类型不确定的时候,就使用<>.将操作的引用数据类型传入即可。<>接受的是一个具体引用数据类型的参数范围。在程序中,只要用到了带有<>的 类或者接口,就要明确传入的具体引用数据类型




/**
 * 第三十七集 泛型的内部原理 及更深应用
 * 泛型是提供给Javac编译器使用的,可以限定集合中的输入类型,
 * 让编译器挡住源程序中的非法输入,编译器编译带类型说明的集合
 * 时会去掉”类型“信息,使程序运行效率不受影响,对于参数化的泛
 * 型类型,getClass()的返回值和原类型完全一样。由于编译生
 * 成的字节码会去掉泛型类型信息,只要能跳过编译器,就可以往某
 * 个泛型集合中加入 其它类型的数据,例如,用反射得到集合,再调
 * 用其add方法即可
 * 
 * 了解泛型
 * ArraList<E>类定义和ArrayList<Integer>类引用中设计如下术语:
 * --整个称为ArrayList<E>泛型类型
 * --ArrayList<E>中的E被称为类型变量或类型参数
 * --整个ArrayList<Integer>称为参数化的类型
 * --ArrayList<Integer>中Integer称为类型参数的实例或实际类型参数
 * --ArrayList<Integer>中的<>念着tyoeof
 * --ArrayList称为原始类型
 * 参数化类型与原始类型的兼容性:
 * --参数化类型可以引用一个原始类型的对象,编译报告,例如:
 * Collection<String> c = new Vector();
 * --原始类型可以引用一个参数化的类型的对象,编译报告警告,例如:
 * Collection c = new Vector<String>();
 * 原来的方法需要接受一个新的参数,新的类型也要传进去
 * 参数化类型不考虑类型参数的继承关系:
 * --Vector<String> v = new Vector<Object>(); //错误。。
 * 不写<Object>没错,写了就成明知故犯了。。
 * --Vector<Object> v = new Vector<String>(); //也错误
 * 
 * 在创建数组实例时,数组的元素不能使用参数化的类型,例如,下面语句是错误的
 * Vector<Integer> vectorList[] = new Vector<Integer>[10]
 * 思考题:线面代码会报错吗?
 * Vector v1 = new Vector<String>();
 * Vector<Object> v = v1;  

 */


泛型的特点

1.泛型技术是给编译器使用的技术,用于编译时期,确保了类型的安全。运行时会将泛型去掉,生产的class文件中是不带有泛型的,这个称为泛型的擦除。

为什么要擦除呢?是为了兼容运行的类加载器。同时泛型也有补偿补偿,在运行时,通过泛型元素的类型进行转换动作,不用使用者再强制转换了。

代码演示:创建一个ArrayList对象,存储的是String类型对象,怎样建Integer类型的对象存入到ArrayList中




/**
 * 第三十八集 泛型的通配符扩展应用
 * 泛型中的通配符。。
 * 问题:
 * --定义一个方法,该方法用于打印出任意参数化类型的集合中的所有数据,该方法如何定义
 * 错误方式:public static void printCollection(Collection<Object> cols){
for(Object obj:cols){
System.out.println(obj);
}
cols.add("String");没错
cols = new HashSet<Date>();会报错误
}

正确方式:public static void printCollection(Collection<?> cols){
for(Object obj:cols){
System.out.println(obj);
}
//cols.add("String");错误,因为他不知道自己未来匹配就一定是Sring
cols.size();//没有错误,此方法与参数类型没有关系
cols = new HashSet<Date>();
}

总结:
使用?通配符可以引用其他各种参数化的类型,?通配符定义的变量主要作用引用,
可以调用与参数化无关的方法,不能调与参数有关的方法
 * 
 *限定通配符的上边界:
 *--正确:Vector<? extends Number> x = new Veator<Integer>();
 *--错误:Vector<? extends Number> x = new Veator<String>();
 *限定通配符的下边界:
 *--正确:Vector<? super Integer> x = new Veator<Number>();
 *--错误:Vector<? super Integer> x = new Veator<Byte>();
 *提示限定符总是包括自己

 */

package cn.itcast.day2;


import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class GenericTest {


/**
* @param args
* @throws NoSuchMethodException 
* @throws InvocationTargetException 
* @throws IllegalAccessException 
* @throws SecurityException 
* @throws IllegalArgumentException 
*/
public static void main(String[] args) throws IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
// TODO Auto-generated method stub
ArrayList collection1 = new ArrayList();
collection1.add(1);
collection1.add(1L);
collection1.add("abc");
//int i = (Integer)collection1.get(1);

/**
* 在原始的类上延长一下
*/
ArrayList<String> collection2 = new ArrayList();
//collection2.add(1);
//collection2.add(1L);
collection2.add("abc");
String element = collection2.get(0);

ArrayList<Integer> collection3 = new ArrayList<Integer>();
System.out.println(collection3.getClass() == collection2.getClass());
/**
* 透过编译器利用反射,泛型是给编译器看的
*/
collection3.getClass().getMethod("add", Object.class).invoke(collection3, "abc");
System.out.println(collection3.get(0));

printCollection(collection3);
//Class<Number> x = String.class.asSubclass(Number.class);

}

public static void printCollection(Collection<?> collection){
//collection.add("abc");
System.out.println(collection.size());
Class<?> y;
Class<String> x;//Class.forName("java.lang.String");

/**
* 泛型的综合应用
*/
HashMap<String, Integer> maps = new HashMap<String, Integer>();
maps.put("zxx", 28);
maps.put("lhm", 28);
maps.put("flx", 28);

/**
* 变量命名可以起方法返回的结果
* 泛型的实际蚕食类型又是一个参数化的类型
*/
Set<Map.Entry<String,Integer>> entrySet = maps.entrySet();
for(Map.Entry<String, Integer> entry : entrySet){
System.out.println(entry.getKey() + ":" + entry.getValue());


/**
* 他们取公约共同类型
*/
add(3,5);
Number x1 = add(3.5,3);
Object x2 = add(3,"abc");

}

private static <T> T add(T x,T y){
return null;
}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值