和Java泛型谈谈
2016-04-18 10:53
501 查看
泛型,把类型参数化。
泛型的命名规则:
不要小写字母表示泛型名字,虽然这也没什么错。如果可以的话,泛型就用“T”来表示。
还有就是类上的泛型和方法上的泛型,名字尽量不要相同。
它在JDK1.5之后出现,主要的作用是解决安全问题
比如下面的安全问题:
ArrayList可以添加任何类型的元素,该方法在程序编译时并不会出现问题。但是在迭代取值时,Integer类型的值无法转换为String,会出现ClassCastException异常。
而避免这种问题的,就是指定ArrayList的元素的类型,把类型参数化。比如这样:
本例子中,泛型可以把一些错误提前到了编译时期,方便了调试。而且在迭代时,不再需要强制转化。
1,泛型定义在类上
ArrayList类上的泛型
ArrayList al=new ArrayList();
传递进去的类的泛型是String,而定义在类上的泛型,在整个类中都是有效的。
类上的泛型可以由一个也可以由多个:
2,泛型定义在方法上
泛型定义在类上后,操作的类型就固定了。比如下面的写法就有问题:
为了让不同的方法操作不同的类型,我们可以不把泛型定义在类上,而是定义在方法上。
注意的是泛型如果定义在方法上,只对该方法是有效的。
如下:
当然也可以在类上定义泛型,而在方法上也定义泛型来操作不同类型。如:
静态方法的泛型:
静态方法访问类上的泛型,编译出错。原因是,建立对象后才会有泛型。
比如ArrayList al=new ArrayList();
我们知道静态成员是先加载的。
既然静态方法无法访问类上的泛型,我们可以为它在方法上定义泛型。
3,泛型定义在接口上
泛型的命名规则:
不要小写字母表示泛型名字,虽然这也没什么错。如果可以的话,泛型就用“T”来表示。
还有就是类上的泛型和方法上的泛型,名字尽量不要相同。
它在JDK1.5之后出现,主要的作用是解决安全问题
比如下面的安全问题:
private static void method_1() { ArrayList al=new ArrayList(); al.add("abc01"); al.add("abc0991"); al.add("abc014"); al.add(4); Iterator it=al.iterator(); while(it.hasNext()){ String next=(String)it.next(); System.out.println(next); } }
ArrayList可以添加任何类型的元素,该方法在程序编译时并不会出现问题。但是在迭代取值时,Integer类型的值无法转换为String,会出现ClassCastException异常。
而避免这种问题的,就是指定ArrayList的元素的类型,把类型参数化。比如这样:
ArrayList<String> al=new ArrayList<String>(); al.add("abc01"); al.add("abc0991"); al.add("abc014"); //al.add(4); 编译时提示错误
本例子中,泛型可以把一些错误提前到了编译时期,方便了调试。而且在迭代时,不再需要强制转化。
Iterator<String> it=al.iterator(); while(it.hasNext()){ System.out.println(it.next()); }
1,泛型定义在类上
ArrayList类上的泛型
public class ArrayList<E> extends AbstractList<E>
ArrayList al=new ArrayList();
传递进去的类的泛型是String,而定义在类上的泛型,在整个类中都是有效的。
类上的泛型可以由一个也可以由多个:
class GenericForClass1<T>{ private T temp; private void set(T t){ this.temp=t; } private T get(){ return temp; } private void print(){ System.out.println(temp); } } private void generic_1() { GenericForClass1<Integer> generic= new GenericForClass1<Integer>(); generic.set(1); generic.print(); }
class GenericForClass2<T1,T2>{ private T1 t1; private T2 t2; private void setT1(T1 t){ this.t1=t; } private T1 getT1(){ return t1; } private void setT2(T2 t){ this.t2=t; } private T2 getT2(){ return t2; } private void print(){ System.out.println(t1+"----"+t2); } } private void generic_1() { GenericForClass2<Integer,String> generic= new GenericForClass2<Integer,String>(); generic.setT1(1); generic.setT2("ronaldo"); generic.print(); }
2,泛型定义在方法上
class GenericForClass1<T>{ private T temp; private void set(T t){ this.temp=t; } private T get(){ return temp; } private void print(){ System.out.println(temp); } }
泛型定义在类上后,操作的类型就固定了。比如下面的写法就有问题:
GenericForClass1<Integer> generic= new GenericForClass1<Integer>(); eneric.set("1");//编译出错
为了让不同的方法操作不同的类型,我们可以不把泛型定义在类上,而是定义在方法上。
注意的是泛型如果定义在方法上,只对该方法是有效的。
如下:
class GenericForClass1{ private <T>void show(T t){ System.out.println(t); } } private void generic_1() { GenericForClass1 generic= new GenericForClass1(); generic.show("1"); generic.show(1); }
当然也可以在类上定义泛型,而在方法上也定义泛型来操作不同类型。如:
class GenericForClass1<T>{ private T t; private void set(T t){ this.t=t; } private T get(){ return t; } private void print(){ System.out.println(t); } private <S>void show(S s){ System.out.println(s); } } private void generic_1() { GenericForClass1<Integer> generic= new GenericForClass1<Integer>(); generic.set(1); generic.set("1");//编译错误,set方法的泛型和类是绑定的 generic.print(); generic.show("1"); }
静态方法的泛型:
class Demo1<T>{ private void show(T t){ System.out.println(t); } private <T>void set(T t){ System.out.println(t); } //编译时会出现错误 private static <T> void method(T t){ System.out.println(t); } }
静态方法访问类上的泛型,编译出错。原因是,建立对象后才会有泛型。
比如ArrayList al=new ArrayList();
我们知道静态成员是先加载的。
既然静态方法无法访问类上的泛型,我们可以为它在方法上定义泛型。
private static <S> void method(S s){ System.out.println(s); }
3,泛型定义在接口上
//泛型定义在接口上 interface MyInter<T>{ void access(T t); } //实现接口指定泛型 class MyImpl1 implements MyInter<String>{ @Override public void access(String t) { } } //实现接口后不知道传递什么类型 class MyImpl2<T> implements MyInter<T>{ @Override public void access(T t) { } }
相关文章推荐
- java Zip压缩输入输出流问题
- java基础(8)--深入理解Java.String
- java开发环境搭建
- spring junit 单元测试
- java中volatile关键字的含义
- 【Spring实战】—— 6 内部Bean
- Java基础第二章
- 让网页中的Java Script代码自动执行的三种方法
- java.io.File 删除文件delete()和deleteOnExit()的区别
- java解析XML文件-DOM解析法与SAX解析法
- Java相对路径/绝对路径总结
- java文件下载和导出文件名乱码浏览器兼容性问题
- Spring中Bean的作用域
- JAVA 中BIO,NIO,AIO的理解
- Spring流程
- 三年Java软件工程师应该掌握的技能
- SPRING MVC配置
- Java 流读取本地文件
- JavaSript模块规范 - AMD与CMD
- Java正则表达式简记