范型作用
在java集合容器中经常会用到范型,如 List< String > , Map < String , List < String > >
范型主要作用是在编译的时候可以帮助开发人员避免向容器中放入不一致的类型元素。如声明 Lsit list; 在 添加元素list.add(new Object()) 会报错;
一个泛型接口
interface Operation< T > {
void f1( T t ); //参数为范型
T f2( T t); //返回值范型
}
泛型中的类型参数
上述代码中 就是类型参数 ,类型参数只能代表引用类型 ,类型参数T可以在方法签名和方法体中使用。
菱形句法
List< MyType > list = new AarrayList<>(); 此处 <> 表示菱形句法,可以避免再写一次< MyType > ;
类型擦除
java1.5 以前: List s1 = func1(); //通过func1()得到一个List集合,假设集合内元素为String
java1.5 以后 : List< String > s2 = (List < String >) s1 ;//此处代码表示新的泛型集合兼容 ,java1.5以前的List集合;实现这种兼容的原理是 “类型擦除”
类型擦除:范型的类型参数在编译时可见,编译之后的字节码没有体现;
一个不会编译的例子
public interface OrderCounter {
int totalOrders(Map< String , List< String >> orders);
int totalOrders(Map< String , Integer > orders);
}
上述代码无法编译通过,原因在于类型擦除之后 方法签名一致,同为 int totalOrders(Map)
通配符< ? >
假设我们有一个方法 getList() 返回一个List,但是我们不知道类型参数;
此时可以用 : List< Object > list = getList();
也可以用: List< ? > list = getList(); 当然这样方式得到的list.的get()方法的返回的也是Object对象;
List< Object > 和 List< ? > 区别
List< Object> list1 = new ArrayList< String >(); //虽然String是Object的子类型,但是List< String > 并不是List< Object >的子类,所以编译无法通过
List< ? > list2 = new ArrayList< String >(); //而List< ?>实现容器父子关系 ,List< ?>是List< String >的父类型,编译通过。注意这种写法 list2.add(“asdf”),编译不会通过,也就是说无法添加元素。