Java泛型的注意事项以及使用
2013-10-18 10:22
218 查看
为什么要用泛型呢?JDK5以前,对象保存到集合中就会失去其特性,取出时通常要程序员手工进行类型的强制转换,这样不可避免就会引发程序的一些安全性问题。
比如:
![](http://img.blog.csdn.net/20131018093237484?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvV2lsbENvbGQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
泛型的作用:
JDK5中的泛形允许程序员在编写集合代码时,就限制集合的处理类型,从而把原来程序运行时可能发生问题,转变为编译时的问题,以此提高程序的可读性和稳定性(尤其在大型程序中更为突出)。
注意:泛型是提供给javac编译器使用的,它用于限定集合的输入类型,让编译器在源代码级别上,即挡住向集合中插入非法数据。但编译器编译完带有泛形的java程序后,生成的class文件中将不再带有泛形信息,以此使程序运行效率不受到影响,这个过程称之为“擦除”。
泛形的基本术语,以ArrayList<E>为例:<>念做typeof
ArrayList<E>中的E称为类型参数变量
ArrayList<Integer>中的Integer称为实际类型参数
整个称为ArrayList<E>泛型类型
整个ArrayList<Integer>称为参数化的类型ParameterizedType
泛型的应用:
使用迭代器迭代泛形集合中的元素:
![](http://img.blog.csdn.net/20131018100557250?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvV2lsbENvbGQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
增强for循环迭代泛形集合中的元素:
![](http://img.blog.csdn.net/20131018100707765?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvV2lsbENvbGQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
HashMap中的元素:
¨使用泛形时的几个常见问题:
使用泛型时,泛型类型须为引用类型,不能是基本数据类型
使用泛型时,两边的类型必须一致或者两边只有一边用泛型(为了保持兼容性)
自定义泛型:Java程序中的普通方法、构造方法和静态方法中都可以使用泛型。方法使用泛形前,必须对泛形进行声明,语法:<T>,T可以是任意字母,但通常必须要大写。<T>通常需放在方法的返回值声明之前。
下有两个泛型方法:
实现交换的泛型方法:
效果:
![](http://img.blog.csdn.net/20131018101347906?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvV2lsbENvbGQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
实现颠倒顺序的泛型方法:
效果:
![](http://img.blog.csdn.net/20131018101529671?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvV2lsbENvbGQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
如果一个类多处都要用到同一个泛型,这时可以把泛形定义在类上(即类级别的泛型),语法格式如下:
public class
GenericDao<T> {
privateT field1;
publicvoid save(T
obj){}
publicT getId(int id){}
}
注意:
*
在类级别上定义的泛型,只对类的非静态成员有效
* 静态方法不能使用类定义的泛形,而应单独定义泛形
比如:
泛型的作用:
JDK5中的泛形允许程序员在编写集合代码时,就限制集合的处理类型,从而把原来程序运行时可能发生问题,转变为编译时的问题,以此提高程序的可读性和稳定性(尤其在大型程序中更为突出)。
注意:泛型是提供给javac编译器使用的,它用于限定集合的输入类型,让编译器在源代码级别上,即挡住向集合中插入非法数据。但编译器编译完带有泛形的java程序后,生成的class文件中将不再带有泛形信息,以此使程序运行效率不受到影响,这个过程称之为“擦除”。
泛形的基本术语,以ArrayList<E>为例:<>念做typeof
ArrayList<E>中的E称为类型参数变量
ArrayList<Integer>中的Integer称为实际类型参数
整个称为ArrayList<E>泛型类型
整个ArrayList<Integer>称为参数化的类型ParameterizedType
泛型的应用:
使用迭代器迭代泛形集合中的元素:
增强for循环迭代泛形集合中的元素:
HashMap中的元素:
import java.util.*; import java.util.Map.Entry; public class MapTest{ public static void main(String [] args){ Map<Integer,String> map=new HashMap<Integer,String>(); map.put(1,"x"); map.put(2,"a"); map.put(3,"z"); map.put(4,"s");//添加数据 /** *两种遍历Map集合中数据的方法 */ //通过set来遍历 Set<Integer> set=map.keySet();//返回键值的set视图 Iterator<Integer> it=set.iterator();//在这里,如果不加上泛型约束的话,就无法找到需要的类型 while(it.hasNext()){ Integer e=it.next(); String v=map.get(e); System.out.println(v); } //通过Entry来遍历 Set<Entry<Integer,String>> entrys=map.entrySet();//返回映射项的set视图 Iterator<Entry<Integer,String>> its=entrys.iterator(); while(its.hasNext()){ Entry<Integer,String> entry=its.next(); System.out.println(entry.getKey()+"->"+entry.getValue()); } } }
¨使用泛形时的几个常见问题:
使用泛型时,泛型类型须为引用类型,不能是基本数据类型
使用泛型时,两边的类型必须一致或者两边只有一边用泛型(为了保持兼容性)
自定义泛型:Java程序中的普通方法、构造方法和静态方法中都可以使用泛型。方法使用泛形前,必须对泛形进行声明,语法:<T>,T可以是任意字母,但通常必须要大写。<T>通常需放在方法的返回值声明之前。
下有两个泛型方法:
实现交换的泛型方法:
import java.util.Arrays; import java.util.List; //编写泛型方法,实现数组元素交换 public class Swap { /** * 将数组中指定两个位置的元素进行交换 */ public static <T> void swap(T[] arr,Integer pos1,Integer pos2){ T temp=arr[pos1];//记录第一个值 arr[pos1]=arr[pos2];//交换 arr[pos2]=temp; } public static void main(String[] args) { String []arr={"a","b","c"}; swap(arr,0,arr.length-1); List list=Arrays.asList(arr);//把数组转换为集合 System.out.println(list); } }
效果:
实现颠倒顺序的泛型方法:
import java.util.Arrays; import java.util.List; //编写一个泛型方法,接受一个任意数组,并颠倒数组中的所有元素 public class Reserve { public static void main(String[] args) { Integer[] arr={1,2,3,4,5,6,7,8,9,0}; swap(arr); List list=Arrays.asList(arr); System.out.println(list); } /** * 泛型方法的定义权限 <T>修饰符 返回值 方法名(参数列表) * @param <T> * @param arr */ public static <T> void swap(T[] arr){ int start=0; int end=arr.length-1; while(true){ if(start>=end){ break; } T temp=arr[start]; arr[start]=arr[end]; arr[end]=temp; /*以上的操作时将首位两个元素不断的交换, *直到前一个元素的下标大于等于后一个下标为止 */ start++; end--; } } }
效果:
如果一个类多处都要用到同一个泛型,这时可以把泛形定义在类上(即类级别的泛型),语法格式如下:
public class
GenericDao<T> {
privateT field1;
publicvoid save(T
obj){}
publicT getId(int id){}
}
注意:
*
在类级别上定义的泛型,只对类的非静态成员有效
* 静态方法不能使用类定义的泛形,而应单独定义泛形
相关文章推荐
- zeromq 在ubuntu 下的编译命令,以及使用时的注意事项
- 构造器内书写异常以及使用的注意事项---Thinking in java
- oracle 开窗函数的使用,表的外关联,子查询的封装以及where使用的注意事项
- 黑马程序员-OC语言-self修饰变量以及使用总结和注意事项(听课笔记)
- Android中AsyncTask的使用场景、使用时的注意事项以及如何关闭
- string浅拷贝以及在dll中使用的注意事项
- Hibernate 一对多 如何建立表结构以及如何使用的注意事项和实例
- 关于使用存储过程的一些好处以及注意事项
- Qt中如何使用样式表QPalette以及相关注意事项
- 如何不用oracle client直接使用plsql远程连接oracle数据库以及需要注意的事项
- QFTP的配置使用以及避免下载文件为0kb的注意事项
- MySQL索引类型总结和使用技巧以及注意事项
- Qt中如何使用样式表QPalette以及相关注意事项(转)
- [原]SWFObject FAQ 使用swfobject以及flash的注意事项 中文翻译版
- Android基础 Android AsyncTask使用注意事项以及总结
- Qt中如何禁掉所有UI操作以及注意事项(处理各个widget的eventFilter这一层,但是感觉不好,为什么不使用QApplication呢)
- 通过项目中定位的一个问题:学习ionic框架$ionicPopover的使用以及注意事项
- MySQL索引类型总结和使用技巧以及注意事项
- 使用aidl的项目结构以及小的注意事项
- CSS中渐变背景的使用以及注意事项