码迷,mamicode.com
首页 > 编程语言 > 详细

Java泛型的认识

时间:2015-03-31 14:13:42      阅读:170      评论:0      收藏:0      [点我收藏+]

标签:

希望弄懂:
一. 泛型的好处
二. 表述
三. <R extends T>的作用
四. <? super T>,<? extends T>作为参数类型的作用
五. wildcard嵌套 <? extends|super ? extends|super T>
 
一. JDK1.5 引入了泛型,好处:
1. 编译时,类型检查
2. 避免类型转换
 
例如,
技术分享
ArrayList list = new ArrayList();
list.add("str1")
System.out.prinntln((String)list.get(0)).length());
JDK1.4的写法
缺陷:
1. 没有类型保证,如果list.add(new Object()); 那么(String)list.get(0); 就会ClassCastException
2. 没有使用list中的元素都要强制转换
 
在使用泛型,就方便多了
技术分享
ArrayList<String> list = new ArrayList<String>();
list.add("str1");
System.out.println(list.get(0).length());
JDK1.5写法
对于JDK1.7或以上,还进一步简化:
技术分享
ArrayList<String> list = new ArrayList<>();
JDK1.7写法

 后面会自动添加类型;

 
二. 几种表述:
1. 泛型静态函数
public class C {
  public static <T> T foo(T v) {
    return null;
  }
}
//用法:
String ret = C.foo("str");

 2. 泛型类

public class C<T> {
  public T foo(T v) {
    return null;
  }
}
//用法:
C<String> instance = new C<String>();
String ret = instance.foo("str");
3. 泛型成员函数
public class C {
  public <T> T foo(T v) {
    return null;
  }
}
//用法:
C instance = new C();
String ret = instance.foo("str");

 4. 泛型类的泛型成员函数

public class C<R> {
  public <T> T foo(T v1, R v2) {
    return null;
  }
}
//用法:
C<String> instance = new C<String>();
Integer ret = instance.foo(1, "str");
5. 泛型类的泛型静态函数
public class C<R> {
  public static <T> T foo(T v1) {
    return null;
  }
}
// (R的泛型没意义)
Integer ret = C.foo(1);
6. public class C<T> { public static T foo(T v) {return null;} } 不能编译
 
 
三. ,<R extends T>的作用
作为方法的类型,
extends提供R的上限,如<R extends Number>,R可以是Number,Integer,Double等继承Numberl类,起到限制作用。
没有<R super T>,如<R super Number>,R可以是Number, Serializable,由于子类都可以放到父类上,相当于Number,所以没意义
public class C {
  public static <R extends Number> T foo(R v) {
    return v;
  }
}
Integer ret = C.foo(1);
作为类的类型,也是类似的
public class C<R extends Number> {
  public R foo(R v) {
    return v;
  }
}
C<Integer> instance = new C<Integer>();
Integer ret = instance.bar(1);
那么,采用<R extends Number>的好处有哪些呢:
1. v能知道是Number或子类,能提早使用Number的方法,v.intValue();
2. 现在具体化的范围,如C<String>编译错误
 
至于class C<R super Number> 同样不支持。
 
四. <? super T>,<? extends T>作为参数类型的作用
先说一下,泛型删除
<?>代表没类型,如果作为参数类型,就只能接收null值;如果作为返回类型,就只能返回Object;一般这类,只能用没有泛型的函数,或者说,不关心其类型
public class C<T> {
  public T foo(T v) {
    return v;
  }
  public String bar(int i) {
    return "" + i;
  }
}
 
C<?> instance = new C<?>();
Object ret = instance.foo(null); // 这个用法没实际作用
String sRet = instance.bar(1); // 主要调用没有类型部分

既然C<?>不用考虑T的类型,那么具体化也可以,如 C<?> instance = new C<String>();

这样设计,创建者能根据自己需要设置类型,而使用者就不用关系类型

如果需要使用数据类型,就可以使用
C<? super Number> 或 C<? extends Number>
C<? super Number> 适合传入类型,返回没类型,容器能向下兼容
C<? super Number> instance = new C<Object>();
Object ret = instance.foo(new Integer(0)); // 接受Number的参数;但返回值Object,一般用于,修改数据。
C<? extends Number> 适合返回类型,而且不能传入参数,容器能向上兼容
C<? extends Number> instance = new C<Integer>();
Number ret = instance.foo(null); // 不接收参数,但返回Number,一般用于,获取数据。

 

五. wildcard嵌套 <? extends|super ? extends|super T>
这部分其实没什么意义,可以看成<? super T>和<? extends T>,仅仅为了语言的完整性
以下用例子说明:
技术分享
public class C<T> {
  public C<? super T> foo(C<? super T> v) {
    return v;
  }
  public C<? extends T> bar(C<? extends T> v) {
    return v;
  }
}
 
C<? super Number> s = null;
C<? extends Number> e = null;
 
C<? super Number> sInstance = new C<Object>();
C<? super Number> ret1 = sInstance.foo(null);
C<?> ret2 = sInstance.bar(e);
 
C<? extends Number> eInstance = new C<Integer>();
C<?> ret3 = eInstance.foo(s);
C<? extends Number> ret4 = eInstance.bar(null);
View Code
归纳如下:
<? super ? super T> 参数类型:null,返回值<? super T>
<? extends ? super T> 参数类型:<? extends T>,返回值<?>
<? super ? extends T> 参数类型<? super T>,返回值<?>
<? extends ? extends T> 参数类型为null, 返回值<? extends T>
 
 

Java泛型的认识

标签:

原文地址:http://www.cnblogs.com/shifting/p/4380483.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!