您当前的位置: 首页 > 学无止境 > 心得笔记 网站首页心得笔记
javase第三季学习笔记-泛型
发布时间:2017-08-10 15:37:09编辑:雪饮阅读()
泛型
• JDK 1.5之后出现了新的技术 —— 泛型(Generic),此技术的最大特点是类中的属性的类型可以由外部决定
• 而且在声明类的时候应该采用如下的形式:
• class 类名称<泛型类型,泛型类型,…>{
•
• }
• 在使用泛型操作的时候,实际上有很多小的注意点,例如:构造方法上依然可以使用泛型或者有一种称为泛型的擦除。
•
• 相关术语:
• ArrayList<E>:E称为类型变量或类型参数
• ArrayList<Integer>:称为参数化的类型
• ArrayList<Integer>:中的Integer称为类型参数的实例或实际参数类型
• ArrayList<Integer>:<>称为 type of
• ArrayList:称为原始类型
• 参数化类型与原始类型的兼容性:
• Collection<String> c = new Vector();
• Collection c = new Vector<String>();
• 参数化类型不考虑类型参数的继承关系:
• Vector<String> v = new Vector<Object>(); //错误
• Vector<Object> v = new Vector<String>(); //错误
• 正确:
• Vector v = new Vector<String>();
• Vector<Object> v2 = v;
• 错误:
• Vector<String>[] vs =
• new Vector<String>()[10];
• 定义数组不能使用泛型
• 两个问题:
• 1、 在构造方法上引用泛型
• 2、如果在使用的时候没有指定泛型的话,则表示擦除泛型。泛型一旦擦出之后,将按照Object进行接收,以保证程序不出现任何的错误。
通配符
• 问题:
• Children<Object> c1 = new Children<Object>();
• Children<Integer> c2 = new Children<Integer>() ;
• c1 = c2; // 此时无法转换
• “?”表示的是可以接收任意的泛型类型,但是只是接收输出,并不能修改。
• 提示:
• 使用通配符可以引用其他各种参数化类型,通配符定义的变量主要用作引用,可以调用与参数无关的方法,
• 不能调用与参数有关的方法。
• 泛型上限就指一个的操作泛型最大的操作父类,例如,现在最大的上限设置成“Number”类型,那么此时,所能够接收到的类型只能是Number及其子类(Integer)。
• 泛型的上限通过以下的语法完成:
• ? extends 类
• 泛型的下限指的是只能设置其具体的类或者父类。设置的语法如下:
• ? super 类
泛型方法
• 泛型除了在类中定义之外,还可以在方法上定义,而且在方法上使用泛型,此方法所在的类不一定是泛型的操作类。
• 定义一个方法,实现任意类型数组中两个位置值的调换
• public static <T> T[] func(T[] array,int i,int t){
• T temp = array[i];
• array[i] = array[t];
• array[t] = temp;
• return array;
• }
泛型的嵌套使用
• 还记得我们在讲解集合Map的时候吗?
• Set<Entry<Integer, String>> entrys = map.entrySet();
代码示例:
入口程序:
package com.vince.generic;
public class GenericDemo {
public static void main(String[] args) {
Children<Integer> c1=new Children<Integer>("小小白",3);
Children<Float> c2=new Children<Float>("小小黑",1.6f);
Children<String> c3=new Children<String>("小小黄","二");
//泛型的特殊语法一
Children<String> c4=new Children("小小花","三");
//泛型的特殊语法二
Children c5=new Children<String>("小小红","四");
//表示泛型擦除,擦除后则使用Object类型
Children c6=new Children();
int age1=c1.getAge();
float age2=c2.getAge();
String age3=c3.getAge();
String age4=c4.getAge();
Children<Integer> c7=new Children<Integer>();
Children<String> c8=new Children<String>();
print(c1);
print(c2);
//使用泛型上限
Children2<Integer> c9=new Children2<Integer>();
//使用泛型下限
fun(c3);
//使用泛型方法
String[] names={"aa","bb","cc"};
names=fun2(names,0,2);
for (String name : names) {
System.out.println(name);
}
}
//定义泛型方法
public static <T> T[] fun2(T[] array,int i,int t){
T temp=array[i];
array[i]=array[t];
array[t]=temp;
return array;
}
//定义泛型下线
public static void fun(Children<? super String> c){
System.out.println(c.getAge());
}
//使用通配符?定义参数
public static void print(Children<?>c){
//使用通配符接收,只能输出,不能修改
System.out.println("我的年龄是:"+c.getAge());
}
}
Children类:
package com.vince.generic;
//使用泛型定义
public class Children<T> {
private String name;
private T age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public T getAge() {
return age;
}
public void setAge(T age) {
this.age = age;
}
public Children() {
super();
}
public Children(String name, T age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Children [name=" + name + ", age=" + age + "]";
}
}
Children2类:
package com.vince.generic;
//使用泛型定义
//定义泛型的上限为Number
public class Children2<T extends Number> {
private String name;
private T age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public T getAge() {
return age;
}
public void setAge(T age) {
this.age = age;
}
public Children2() {
super();
}
public Children2(String name, T age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Children [name=" + name + ", age=" + age + "]";
}
}
泛型接口
• 泛型不光可以在类上使用,还可以在接口中进行定义。操作的语法如下:
• interface 接口名称<泛型类型,泛型类型,…>{}
代码示例:
package com.vince.generic;
//使用泛型定义接口
public interface IEat<T> {
public void eat(T food);
}
class IEatImpl<T> implements IEat<T>{
public void eat(T food) {}
}
关键字词:javase,泛型