Java 泛型详解
来源:互联网 发布:数据库 锁定客户群 编辑:程序博客网 时间:2024/06/05 23:31
首先在没有泛型之前,一旦把一个对象丢进java集合中,集合就会忘记对象的类型,把所有对象当成Object类型来处理。当程序从集合中取出对象时,就需要进行强制类型转换,这种强制类型转换不仅代码臃肿,而且容易引起ClassCastException异常。
- public class ListErr
- {
- public static void main(String[] args)
- {
- //创建一个只想保存字符串的List集合
- List strList = new ArrayList();
- strList.add("Struts2权威指南");
- strList.add("基于J2EE的Ajax宝典");
- strList.add("轻量级J2EE企业应用实战");
- //”不小心“把一个Integer对象”丢进"了集合
- strList.add(5);
- for (int i = 0; i < strList.size() ; i++ )
- {
- //因为List里取出的全部是Object,所以必须强制类型转换
- //最后一个元素将出现ClassCastException异常
- String str = (String)strList.get(i);
- }
- }
- }
- 为了解决这个问题,在1.5前都采用,创建个List对象的方法,但每遇到个集合都要建个对象,eg
- class StrList
- {
- private List strList = new ArrayList();
- //定义StrList的add方法
- public boolean add(String ele)
- {
- return strList.add(ele);
- }
- //重写get方法,将get方法的返回值类型改为String类型
- public String get(int index)
- {
- return (String)strList.get(index);
- }
- public int size()
- {
- return strList.size();
- }
- }
- public class CheckType
- {
- public static void main(String[] args)
- {
- //创建一个只想保存字符串的List集合
- StrList strList = new StrList();
- strList.add("Struts2权威指南");
- strList.add("基于J2EE的Ajax宝典");
- strList.add("轻量级J2EE企业应用实战");
- //下面语句不能把Integer对象“丢进”集合中,将引起编译异常
- strList.add(5);
- System.out.println(strList);
- for (int i = 0; i < strList.size() ; i++ )
- {
- //因为StrList里元素的类型就是String类型,所以无需强制类型转换
- String str = strList.get(i);
- }
- }
- }
- 有了泛型就方便了,eg
- public class GenericList
- {
- public static void main(String[] args)
- {
- //创建一个只想保存字符串的List集合
- List<String> strList = new ArrayList<String>();
- strList.add("Struts2权威指南");
- strList.add("基于J2EE的Ajax宝典");
- strList.add("轻量级J2EE企业应用实战");
- //下面代码将引起编译错误
- strList.add(5);
- for (int i = 0; i < strList.size() ; i++ )
- {
- //下面代码无需强制类型转换
- String str = strList.get(i);
- }
- }
- }
当创建带泛型的自定义类时,在定义该类构造器时,构造器名还是和类名一样,不要增加泛型声明。
从泛型类派生子类,接口,父类不能包含类型形参。
下面例子就是错误的。
public class A extends B<T>{},
使用类型通配符“?’”, 它可以匹配任何类型,
public void test(List <?>){}
- 使用时注意:List<String>不是List<Object>子类
- 特殊的泛型(带类型通配符和类型上限),eg
- public class Apple<T extends Number>
- {
- T col;
- public static void main(String[] args)
- {
- Apple<Integer> ai = new Apple<Integer>();
- Apple<Double> ad = new Apple<Double>();
- //下面代码将引起编译异常
- //因为String类型传给T形参,但String不是Number的子类型。
- Apple<String> as = new Apple<String>();
- }
- }
- java泛型不支持泛型数组(List<String> aa=new ArrayList<String>[10];),因为java泛型的设计原则是没有unchecked警告就没有ClassCastExcepiton. 我建议大家遇到集合数组等的时候,自己来检验数据的类型,eg
- public class test {
- public static void main(String[] args) {
- ArrayList[] aa = new ArrayList[10];
- List<Integer> li = new ArrayList<Integer>();
- li.add(3);
- ((Object[]) aa)[1] = li;
- Object target = aa[1].get(0);
- if (target instanceof Integer) {
- Integer s = (Integer) target;
- System.out.println(s);
- }
- }
- }
- 由于java的泛型只是编译时做下检验,大家不要想的过于强大,他的最大作用只是增强代码的可读性,别的方面也没见多大的作用。
什么时候写泛型?有什么好处?
最简单的体现,只要使用到了带有<>的类和接口,就指定具体对象类型。
泛型的好处:
1, 将运行时出现的ClassCastException问题,再编译时期给解决了。运行就安全了。
2, 避免了强制转换的麻烦。
所以泛型就是JDK1.5后出现的一个安全机制。
泛型的理解?
首先在没有泛型之前,一旦把一个对象丢进java集合中,集合就会忘记对象的类型,把所有对象当成Object类型来处理。
当程序从集合中取出对象时,就需要进行强制类型转换,这种强制类型转换不仅代码臃肿,而且容易引起ClassCastException异常。
1,泛型就是传参数。
2,泛型替代了Object。
什么是泛型的擦除和补偿?
泛型是编译时期的安全机制。
编译时,通过泛型机制,编译器多了多元素类型进行检查的步骤。
如果检查通过,产生的class文件时不带有泛型的:也就是泛型的擦除。
泛型的补偿:在对元素存储的时候,可以完成类型的判断。
可是在对元素取出的时候,怎么用指定的类型来接收呢?
JVM运行时,会获取元素的类型,并用该类型对元素进行转换即可。
什么时候使用泛型类?
当类中要操作的引用数据类型不确定的时候,以前使用的是共性类型Object,
现在可以使用泛型来解决。
什么时候使用泛型方法?
当方法操作的引用数据类型不确定的时候,就使用泛型方法。
如果方法是静态的,是无法访问类上定义的泛型的。
如果该方法还需要泛型。
必须将泛型定义在方法上。
泛型的限定。
如果要对操作的类型进行限定,只操作一部分类型时,可以使用泛型的高级功能。
?extends E:可以接收E类型和E的子类型。这叫泛型的上限。
?super E:可以接收E类型或E的父类型。这叫泛型的下限。
什么时候会用? extends E 呢?(往集合中添加集合的时候经常使用)
一般在存储具体引用类型时,使用这种情况。
因为存储E类型或者E类型的子类型,在取出的时候都可以用E类型来操作这些元素。
这时可以保证类型是安全的。
下限什么时候用?
从集合中取出对象进行操作时,可以使用下限。
例如:比较器。无论集合中的元素对象的类型是什么,只要比较器的指定的类型可以接收这些对象完成比较,就可以了。
所以比较器的类型,可以是集合中当前元素的类型,也可以是该元素类型的父类型。
泛型使用的误区:
1, 凡是安全的都特别严格。一定要保证座左右两边一致。
2, 不能操作特有对象。
参数定义的集合类型是一个范围,而接受的实际参数是以一个实体,该实体肯定会指定该范围中的某一个具体类型。而该类型是创建容器时指定的,到底是哪种类型该方法是不确定的,那么就不可以在该方法内,进行具体类型对象的定义和操作。
建议定义泛型时,左右两边一定要一致。如果不一致要保证一点,左边在声明时可以声明一个类型范围,右边在实例化时指定的具体类型必须是左边类型范围中的一种。
- Java泛型详解
- java泛型详解
- java泛型详解
- Java泛型详解
- Java泛型详解
- java泛型详解
- Java泛型详解
- java泛型详解
- java 泛型详解
- java 泛型详解
- Java 泛型详解
- java 泛型详解
- java 泛型详解
- java泛型详解
- java 泛型详解
- Java泛型详解
- java 泛型详解
- java 泛型详解
- 思科CCNA第三学期第六章答案
- 数组指针malloc空间问题
- HDU 1517 A Multiplication Game 巴什博弈
- Huffman树
- thinkphp对事务回滚的案例
- Java 泛型详解
- 【转载】 java多线程总结
- Awk 入门介绍
- 自学JAVA之Cannot make a static reference to the non-static method分析
- poj训练计划
- slf4j如何打印java异常堆栈信息throwable对象
- Java 正则表达式中量词的贪婪型,勉强型和占有型讲解
- 1011. A+B和C (15)
- Nginx 中 upstream 机制的负载均衡