Java泛型
来源:互联网 发布:ubuntu双系统安装 编辑:程序博客网 时间:2024/06/03 13:06
为什么要使用泛型?
@Testpublic void test1(){List list = new ArrayList();list.add(123);list.add(456);list.add(789);list.add("AA");Iterator it = list.listIterator();while(it.hasNext()){int num = (Integer)it.next();System.out.println(num);}}
结果会有异常
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integerat com.wya.j2se.fanxing.TestDemo.test1(TestDemo.java:17)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)at java.lang.reflect.Method.invoke(Unknown Source)at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)at org.junit.runners.ParentRunner.run(ParentRunner.java:363)at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
类转型异常,因为List实例化时没有限定是哪种类型的,所以默认是Object,我们可以add任意类型的元素,但是当我们想把元素按数字类型输出时就会出现类转型异常,这时就需要泛型了。
泛型的作用:
1. 解决元素存储的安全性问题,只有指定类型才可以添加到集合中:类型安全
2. 解决获取数据元素时,不需要强制类型转换。
如何使用泛型?
interfaceList<T> 和classTestGen<K,V>
其中,T,K,V不代表值,而是表示类型。这里使用任意字母都可以。常用T表示,是Type的缩写。T只能是引用类型,不能使用基本类型。
2.泛型的实例化
List<String> strList = new ArrayList<String>();3.自定义泛型类
public class Order<T> {private Integer id;private String sn;private T t;public Order() {super();// TODO Auto-generated constructor stub}public Order(Integer id, String sn, T t) {super();this.id = id;this.sn = sn;this.t = t;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getSn() {return sn;}public void setSn(String sn) {this.sn = sn;}public T getT() {return t;}public void setT(T t) {this.t = t;}}
@Testpublic void test2(){//实例化对象时指定了泛型为String类型,则Order类里所有的泛型都是String类型//如果没有指定泛型类型,默认是Object类型Order<String> order = new Order<String>();order.setId(1);order.setSn("sn123456");order.setT("订单1");//这里就变成了String类型}
如果定义泛型类时这么表示
public class Order<T extends Number> {...}则表示泛型T必须是Number的子类,所以像String类型就不允许传进来了。
4.泛型方法
泛型方法的格式:
[访问权限] <泛型> 返回类型 方法名([泛型标识 参数名称]) 抛出的异常
public class Order<T> {private Integer id;private String sn;private T t;public Order() {super();// TODO Auto-generated constructor stub}public Order(Integer id, String sn, T t) {super();this.id = id;this.sn = sn;this.t = t;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getSn() {return sn;}public void setSn(String sn) {this.sn = sn;}public T getT() {return t;}public void setT(T t) {this.t = t;}/* * 定义一个泛型方法 */public <E> E getE(E e){return e;}}
@Testpublic void test3(){Order<String> order = new Order<String>();//参数指定是Double类型的,所以返回值自动变成Double类型Double value = order.getE(1.234);System.out.println(value);//1.234}
泛型和继承的关系
如果B是A的一个子类型(子类或者子接口),而G是具有泛型声明的类或接口,G<B>并不是G<A>的子类型!
比如:String是Object的子类,但是List<String>并不是List<Object>的子类。
@Testpublic void test4(){List<Object> list1 = null;List<String> list2 = new ArrayList<String>();//不能把list2赋给list1,编译错误list1 = list2;}
如果想可以实现把带泛型的List赋给别人,可以使用通配符?
@Testpublic void test5(){List<?> list1= null;List<Object> list2 = new ArrayList<Object>();List<String> list3 = new ArrayList<String>();list1 = list2;list1 = list3;}注意两点:
①读取List<?>的对象list中的元素时,永远是安全的,因为不管list的真实类型是什么,它包含的都是Object。
②写入list<?>中的元素时,不行。因为我们不知道?的元素类型,我们不能向其中添加对象。唯一的例外是null,它是所有类型的成员。
所以我们只能读取具有通配符的对象数据,不能写入。
有限制的通配符
<?>允许所有泛型的引用调用
举例:
<?extends Number> (无穷小 , Number]
只允许泛型为Number及Number子类的引用调用
<? super Number> [Number , 无穷大)
只允许泛型为Number及Number父类的引用调用
<? extends Comparable>
只允许泛型为实现Comparable接口的实现类的引用调用
@Testpublic void test6(){List<? extends Number> list1= null;List<Integer> list2 = new ArrayList<Integer>();List<String> list3 = new ArrayList<String>();list1 = list2;//编译错误String不是Number的子类list1 = list3;}
泛型注意事项
1.静态方法中不能使用类的泛型。
2.如果泛型类是一个接口或抽象类,则不可创建泛型类的对象。
3.不能在catch中使用泛型
4.从泛型类派生子类,泛型类型需具体化
- 【java 2】java泛型
- Java 泛型 Java generic
- Java Tutorials_Generics(java泛型)
- Java基础 Java 泛型
- java 泛型
- java泛型
- Java泛型
- Java泛型
- java泛型
- java泛型
- java泛型
- Java 泛型
- Java泛型
- Java 泛型
- JAVA 泛型
- java 泛型
- java泛型
- Java泛型
- sicily1001. 输入输出LL(1)语法分析程序 **
- java 日期加减天数、月数、年数的计算方式
- dropload.js中条件查询时,刷新样式增多问题。
- Javascript知识总结
- eclipse不自动弹出提示(alt+/快捷键失效)
- Java泛型
- JSON对象反序列化为Java对象的时候自定义Date类型的字符串格式
- 动态链接库是什么?怎么用?
- gcc版本和运行环境gdb版本不匹配所引发的调试问题
- mysql 相关索引
- Java正则表达式 去掉括号内任意字符
- spring cloud配置
- Spring学习笔记1
- 使用@JsonProperty解决无法同时使用@JsonIgnore及@NotNull注解