1.简述
CharSequence是String的父类,但List<CharSequence>不是List<String> 的父类。同样的,Class<CharSequence>也不是Class<String>的父类。
为了反映泛型类所持有元素的继承关系,可以用到泛型的边界。
void fun(){
List<String> list=new ArrayList<>();
//下行会报错.CharSequence是String的父类但List<CharSequence>不是List<String> 的父类。
//List<CharSequence> list1=list;
//下行报错
//List<? super CharSequence> list2=list;
//下行不报错
List<? extends CharSequence> list3=list;
}
<? entends A>,可以get,可以调用A类的方法。
<? super A>,可以set。
因为擦除移除了类型信息,所以能用无界泛型参数 (即?)调用的方法只是那些可以用Object调用的方法。
泛型中的extends
它将泛型参数限制为某个类型子集,那么就可以调用该类族的一些方法。泛型参数表中的extends
//: generics/BasicBounds.java
//泛型参数列表的extends
interface HasColor { java.awt.Color getColor(); }
class Colored
{
T item;
Colored(T item) { this.item = item; }
T getItem() { return item; }
// The bound allows you to call a method:
java.awt.Color color() { return item.getColor(); }
}
class Dimension { public int x, y, z; }
// This won't work -- class must be first, then interfaces:
// class ColoredDimension
{
// Multiple bounds:
class ColoredDimension
{
T item;
ColoredDimension(T item) { this.item = item; }
T getItem() { return item; }
java.awt.Color color() { return item.getColor(); }
int getX() { return item.x; }
int getY() { return item.y; }
int getZ() { return item.z; }
}
interface Weight { int weight(); }
// As with inheritance, you can have only one
// concrete class but multiple interfaces:
class Solid
{
T item;
Solid(T item) { this.item = item; }
T getItem() { return item; }
java.awt.Color color() { return item.getColor(); }
int getX() { return item.x; }
int getY() { return item.y; }
int getZ() { return item.z; }
int weight() { return item.weight(); }
}
class Bounded
extends Dimension implements HasColor, Weight {
public java.awt.Color getColor() { return null; }
public int weight() { return 0; }
}
public class BasicBounds {
public static void main(String[] args) {
Solid
solid = new Solid
(new Bounded()); solid.color(); solid.getY(); solid.weight(); } } ///:~
泛型类的extends
//: generics/InheritBounds.java
//泛型类的extends
interface HasColor { java.awt.Color getColor(); }
interface Weight { int weight(); }
class Dimension { public int x, y, z; }
class Bounded
extends Dimension implements HasColor, Weight {
public java.awt.Color getColor() { return null; }
public int weight() { return 0; }
}
class HoldItem
{
T item;
HoldItem(T item) { this.item = item; }
T getItem() { return item; }
}
class Colored2
extends HoldItem
{
Colored2(T item) { super(item); }
java.awt.Color color() { return item.getColor(); }
}
class ColoredDimension2
extends Colored2
{ ColoredDimension2(T item) { super(item); } int getX() { return item.x; } int getY() { return item.y; } int getZ() { return item.z; } } class Solid2
extends ColoredDimension2
{ Solid2(T item) { super(item); } int weight() { return item.weight(); } } public class InheritBounds { public static void main(String[] args) { Solid2
solid2 = new Solid2
(new Bounded()); solid2.color(); solid2.getY(); solid2.weight(); } } ///:~
把第32行做些改变,会有如下报错:
泛型参数中的问号
//: generics/Holder.java
//Fruit是Apple的基类,但Holder
不是Holder
的基类,所以不能向上转型
//Holder
可以向上转型为Holder<? extends Fruit>,此时set()方法不能用,只能用get()
class Fruit{}
class Apple extends Fruit{};
class Orange extends Fruit{};
class Jonathan extends Apple{};
public class Holder
{
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) {
fun1();
System.out.println("******************************");
fun2();
}
/**
* ? extends Fruit 表示fruit持有的是Fruit及其子类。
* Fruit的子类有很多,所以fruit.set(X),无论X是什么都不能编译通过。
* 但Fruit的子类一定拥有Fruit类的方法,所以成员函数可以调用。
*/
static void fun1(){
Holder
Apple = new Holder
(new Apple()); Apple d = Apple.get(); Apple.set(d); // Holder
Fruit = Apple; // Cannot upcast Holder
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 } /** *
表示fruit持有的是Apple及其父类。 * 所以fruit.set(X),无论X只要是Apple及其子类就可以编译通过。因为 父类 x=new 子类()是可以的。 * 但Apple类的成员方法不能再调用了。因为父类不知道子类的方法。 */ static void fun2(){ Holder
Apple = new Holder
(new Apple()); Apple d = Apple.get(); Apple.set(d); // Holder
Fruit = Apple; // Cannot upcast Holder
fruit = Apple; // OK Fruit p = (Fruit) 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()); // ok fruit.set(new Jonathan()); // ok //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 ****************************** java.lang.ClassCastException: Apple cannot be cast to Orange false */