泛型的边界

1.简述

CharSequence是String的父类,但List不是List 的父类。同样的,Class也不是Class的父类。
为了反映泛型类所持有元素的继承关系,可以用到泛型的边界。
void fun(){
		List list=new ArrayList<>();
		//下行会报错.CharSequence是String的父类但List不是List 的父类。
		//List list1=list;
		//下行报错
		//List list2=list;
		//下行不报错
		List list3=list;
	}
,可以get,可以调用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

*/

你可能感兴趣的:(java-语法)