网站排名易下拉教程,空间平面的网页设计素材,怎么在百度创建网站,传播学视角下网站建设研究文章目录 泛型为什么用泛型泛型特性泛型的擦出和补偿自定义泛型在类上自定义泛型在方法上使用泛型在接口上定义泛型 类型通配符 泛型
为什么用泛型
不用泛型
public class User {public static void main(String[] args) {//创建 arraylist 集合Collection arraylist new A… 文章目录 泛型为什么用泛型泛型特性泛型的擦出和补偿自定义泛型在类上自定义泛型在方法上使用泛型在接口上定义泛型 类型通配符 泛型
为什么用泛型
不用泛型
public class User {public static void main(String[] args) {//创建 arraylist 集合Collection arraylist new ArrayList();//把 Person 对象假如 arraylistPerson p new Person();arraylist.add(p);//用迭代器遍历调用 test 方法Iterator it arraylist.iterator();while (it.hasNext()) {Object o it.next();//这里非常麻烦要向下转型所以我们可以用泛型if (o instanceof Person) {Person temp (Person) o;temp.test();}}}
}class Person {public void test() {System.out.println(调用 test 方法);}
}
使用泛型
public class User {public static void main(String[] args) {//创建 arraylist 集合CollectionPerson arraylist new ArrayList();//把 Person 对象假如 arraylistPerson p new Person();arraylist.add(p);//用迭代器遍历调用 test 方法IteratorPerson it arraylist.iterator();while (it.hasNext()) {//这里用了泛型所以代码更简便了也不用向下转型了,并且编译会进行类型检查更安全了Person temp it.next();temp.test();}}
}class Person {public void test() {System.out.println(调用 test 方法);}
}泛型特性
泛型是 java5 的新特性属于编译阶段的功能让开发者指定集合中存储的数据类型
//这里就表示只能存 String 类型数据否则编译阶段报错
ArraylistString al new ArrayListString();作用
类型安全指定集合中元素类型后编译器会进行类型检查如果尝试将类型错误的元素添加到集合中就会在编译时报错避免了运行时出现的错误问题代码简洁避免频繁类型转换因为不用泛型集合就默认返回Object
钻石表达式
java7 的新特性
//后面里的 String 可以省略
Arrayliststring a1 new ArrayList();泛型的擦出和补偿
擦除
泛型提高安全性是编译阶段的技术专门给编译器用的加载类的时候会把泛型擦除掉擦成 Object 类型擦除的本质是让 JDK1.4之前的 和 JDK1.5 能兼容同一个类加载器1.5擦除后为 Object 和 1.4 之前就兼容了
补偿
擦除为 Object 类型所以添加的元素就被转化为 Object 类型同时取出的元素也默认为 Object 类型这里有一个默认的操作他帮你自动把 Object 强转成对应的类型不用强转 自定义泛型
在类上自定义泛型
public class User {public static void main(String[] args) {//下面Person类所有 T 都替换为 StringPersonString p new Person(张三);}
}//如果多个泛型就用 逗号 隔开
class PersonT1 {private T name;public Person(T name){this.name name}public T getName() {return name;}public void setName(T name) {this.name name;}
}这个 T 是自定义的 名字可以随意取 在方法上使用泛型
class PersonR { //这个 T 和 T 对应属于泛型方法R 和 r 对应属于泛型类public T void method(T t, R r)
}在类上定义的泛型静态方法中无法使用如果在静态方法中使用泛型则需要在返回值类型前进行泛型声明
class PersonT1 {public staic void setName(T name) {this.name name;}
} 因为如果静态方法能使用你用类名.方法 (Person.setName)直接调用定义不了泛型直接寄了 如果要在静态上用泛型就要使用自定义泛型方法
class Person {//提前定义好 T1//这个 T 是属于这个方法的泛型public staic T void setName(T name) {this.name name;}
} 在接口上定义泛型
接口继承时定义泛型
interface IA extends IUsbString, Double {}
//当我们去实现IA接口时因为IA在继承IUsu 接口时指定了U 为String R为Double
//在实现IUsu接口的方法时使用String替换U, 是Double替换R
class AA implements IA {Overridepublic Double get(String s) {return null;}Overridepublic void hi(Double aDouble) {}Overridepublic void run(Double r1, Double r2, String u1, String u2) {}
}interface IUsbU, R {int n 10;//U name; 不能这样使用//普通方法中可以使用接口泛型R get(U u);void hi(R r);void run(R r1, R r2, U u1, U u2);//在jdk8 中可以在接口中使用默认方法, 也是可以使用泛型default R method(U u) {return null;}
}
实现接口时定义泛型
//实现接口时直接指定泛型接口的类型
//给U 指定Integer 给 R 指定了 Float
//所以当我们实现IUsb方法时会使用Integer替换U, 使用Float替换R
class BB implements IUsbInteger, Float {Overridepublic Float get(Integer integer) {return null;}Overridepublic void hi(Float aFloat) {}Overridepublic void run(Float r1, Float r2, Integer u1, Integer u2) {}
}interface IUsbU, R {int n 10;//U name; 不能这样使用//普通方法中可以使用接口泛型R get(U u);void hi(R r);void run(R r1, R r2, U u1, U u2);//在jdk8 中可以在接口中使用默认方法, 也是可以使用泛型default R method(U u) {return null;}
}没有指定接口
//没有指定类型默认为Object
//建议直接写成 IUsbObject,Object
class CC implements IUsb { //等价 class CC implements IUsbObject,Object {Overridepublic Object get(Object o) {return null;}Overridepublic void hi(Object o) {}Overridepublic void run(Object r1, Object r2, Object u1, Object u2) {}}interface IUsbU, R {int n 10;//U name; 不能这样使用//普通方法中可以使用接口泛型R get(U u);void hi(R r);void run(R r1, R r2, U u1, U u2);//在jdk8 中可以在接口中使用默认方法, 也是可以使用泛型default R method(U u) {return null;}
}简单来说就是在 继承接口或实现接口时指定泛型
接口中静态成员也不能使用泛型 接口中 类型通配符
泛型不具备继承性
也就是 如果你是 Number 那就是 Number 不能是它的 子类
比如集合定义好了泛型你不确定存声明类型直接 ArrayList?
无限定通配符?可以为任意引用数据类型上限通配符? extends Numbers必须为 Numbers 或者它的子类下限通配符? super Numbers必须为 Numbers 或者它的父类
public class User {public static void main(String[] args) {//啥类型都可以User.test(new ArrayListString());User.test(new ArrayListDouble());//只能是 Number 和 Number 的子类User.test2(new ArrayListDouble());//只能是 Double 和 Double 的父类User.test3(new ArrayListNumber());}public static void test(ArrayList? list){}public static void test2(ArrayList? extends Number list){}public static void test3(ArrayList? super Double list){}
}