深入Java:Generics泛型
作者:网络转载 发布时间:[ 2016/9/28 10:09:32 ] 推荐标签:测试开发技术 Java
造成flist的add()完全不可用的原因是,在这种情况下add()的参数也变成了“? extends Fruit”。下面这个例子可以帮助你进行理解:
//: generics/Holder.java
public class Holder<T> {
private T value;
public Holder() {}
public Holder(T val) { value = val; }
public void set(T val) { value = val; }
public T get() { return value; }
public boolean equals(Object obj) {
return value.equals(obj);
}
public static void main(String[] args) {
Holder<Apple> Apple = new Holder<Apple>(new Apple());
Apple d = Apple.get();
Apple.set(d);
// Holder<Fruit> Fruit = Apple; // Cannot upcast
Holder<? extends Fruit> fruit = Apple; // OK
Fruit p = fruit.get();
d = (Apple)fruit.get(); // Returns ‘Object’
try {
Orange c = (Orange)fruit.get(); // No warning
} catch(Exception e) {
System.out.println(e);
}
// fruit.set(new Apple()); // Cannot call set()
// fruit.set(new Fruit()); // Cannot call set()
System.out.println(fruit.equals(d)); // OK
}
} /* Output: (Sample)
java.lang.ClassCastException: Apple cannot be cast to Orange
true
*///:~
同样的道理,对于上例中的fruit来说,其set()方法的参数变成了“? extends Fruit”,这意味着其接受的参数可以是 任意类型,只需满足上界为Fruit 即可,而编译器无法验证“任意类型”的类型安全性。
反过来看看指定下界的效果:
//: generics/SuperTypeWildcards.java
import java.util.*;
class Jonathan extends Apple {}
public class SuperTypeWildcards {
static void writeTo(List<? super Apple> apples) {
apples.add(new Apple());
apples.add(new Jonathan());
// apples.add(new Fruit()); // Error
}
} ///:~
可以看到,写入操作变得合法。显然,Apple类型满足下界需求,执行写入操作没有安全性问题,而Jonathan是Apple的子类,经过向上转型,也可以符合需求,而Apple的基类Fruit则仍然由于类型不定而被拒绝。
基本类型不能作为类型参数
不能创建List<int>之类,而需使用List<Integer>,但因为自动包装机制的存在,所以写入数据时可以使用基本数据类型。
实现参数化接口
一个类不能实现同一个泛型接口的两种变体,因为擦除会让它们变成相同的接口:
//: generics/MultipleInterfaceVariants.java
// {CompileTimeError} (Won’t compile)
interface Payable<T> {}
class Employee implements Payable<Employee> {}
class Hourly extends Employee
implements Payable<Hourly> {} ///:~
Hourly不能编译。但是,如果从Payable的两种用法中移除掉泛型参数(像编译器在擦除阶段做的那样),这段代码将能够编译。
重载
以下代码无法编译,因为擦除会让两个方法产生相同的签名:
//: generics/UseList.java
// {CompileTimeError} (Won’t compile)
import java.util.*;
public class UseList<W,T> {
void f(List<T> v) {}
void f(List<W> v) {}
} ///:~
自限定类型
class SelfBounded<T extends SelfBounded<T>> { // ...
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系SPASVO小编(021-61079698-8054),我们将立即处理,马上删除。
相关推荐
Java性能测试有哪些不为众人所知的原则?Java设计模式??装饰者模式谈谈Java中遍历Map的几种方法Java Web入门必知你需要理解的Java反射机制知识总结编写更好的Java单元测试的7个技巧编程常用的几种时间戳转换(java .net 数据库)适合Java开发者学习的Python入门教程Java webdriver如何获取浏览器新窗口中的元素?Java重写与重载(区别与用途)Java变量的分类与初始化JavaScript有这几种测试分类Java有哪四个核心技术?给 Java开发者的10个大数据工具和框架Java中几个常用设计模式汇总java生态圈常用技术框架、开源中间件,系统架构及经典案例等

sales@spasvo.com