java泛型extends多个
1.泛型边界
Java泛型编程时,编译器忽略泛型参数的具体类型,认为使⽤泛型的类、⽅法对Object都适⽤,这在泛型编程中称为类型信息檫除。
例如:
[java]
1. class GenericType{
2.    public static void main(String[] args){
3.        System.out.println(new ArrayList<String>().getClass());
4.        System.out.println(new ArrayList<Integer>().getClass());
5. }
6. }
class GenericType{ public static void main(String[] args){  System.out.println(new ArrayList<String>().getClass());  System.out.println(new ArrayList<Inte ger>().getClass());}}
输出结果为:
java.util.ArrayList
java.util.ArrayList
泛型忽略了集合容器中具体的类型,这就是类型檫除。
但是如果某些泛型的类/⽅法只想针对某种特定类型获取相关⼦类应⽤,这时就必须使⽤泛型边界来为泛型参数指定限制条件。
例如:
[java]
1. interface HasColor{
2.    java.awt.Color getColor();
3. }
4. class Colored<T extends HasColor>{
5.    T item;
6.    Colored(T item){
7.        this.item = item;
8. }
9. java.awt.Color color(){
10.    //调⽤HasColor接⼝实现类的getColor()⽅法
11.    Color();
12. }
13. }
14. class Dimension{
15.    public int x, y, z;
17. Class ColoredDimension<T extends Dimension & HasColor>{
18.    T item;
19.    ColoredDimension(T item){
20.        this.item = item;
21. }
22. T getItem(){
23.    return item;
24. }
25. java.awt.Color color(){
26.    //调⽤HasColor实现类中的getColor()⽅法
途安2013款
27.    Color();
28. }
29. //获取Dimension类中定义的x,y,z成员变量
30. int getX(){
31.    return item.x;
32. }
33. int getY(){
34.    return item.y;
35. }
36. int getZ(){
37.    return item.z;
38. }
39. }
40. interface Weight{
41.    int weight();
42. }
43. class Solid<T extends Dimension & HasColor & Weight>{
44.    T item;
45.    Solide(T item){
46.        this.item = item;
47. }
gx748. T getItem(){
49.    return item;
50. }
51. java.awt.Color color(){
52.    //调⽤HasColor实现类中的getColor()⽅法
53.    Color();
54. }
55. //获取Dimension类中定义的x,y,z成员变量
56. int getX(){
法拉利599 gto57.    return item.x;
58. }
59. int getY(){
60.    return item.y;
61. }
62. int getZ(){
63.    return item.z;
64. }
65. int weight(){
66.    //调⽤Weight接⼝实现类的weight()⽅法
67.    return item.weight();
68. }
69. }
70. class Bounded extends Dimension implements HasColor, Weight{
71.    public java.awt.Color getColor{
72.        return null;
73. }
74. public int weight(){
75.    return 0;
76. }
77. }
78. public class BasicBounds{
车辆估价在线查询
79.    public static void main(String[] args){
80.        Solid<Bounded> solid = new Solid<Bounded>(new Bounded());
81.        lor();
82.        X();
83.        Y();
84.        Z();
85.        solid.weight();
86. }
87. }
interface HasColor{ java.awt.Color getColor();}class Colored<T extends HasColor>{ T item; Colored(T item){  this.item = item;}java.awt.Color color(){ //调⽤HasColor接⼝实现类的getColor()⽅法Color();}}class Dimension{ public int x, y, z;}Class ColoredDimension<T extends Dimension & Has Color>{ T item; ColoredDimension(T item){  this.item = item;}T getItem(){ return item;}java.awt.Color color(){ //调⽤HasColor实现类中的getColor()⽅法ret Color();}//获取Dimension类中定义的x,y,z成员变量int getX(){ return item.x;}int getY(){ return item.y;}int getZ(){ return
item.z;}}interface Weight { int weight();}class Solid<T extends Dimension & HasColor & Weight>{ T item; Solide(T item){  this.item = item;}T getItem(){ return item;}java.awt.Color color(){ //调⽤HasColor实现类中的getColor()⽅法Color();}//获取Dimension类中定义的x,y,z成员变量int getX(){ return item.x;}int getY(){ retu rn item.y;}int getZ(){ return item.z;}int weight(){ //调⽤Weight接⼝实现类的weight()⽅法return item.weight();}}class Bounded extends Dimension impleme nts HasColor, Weight{ public java.awt.Color getColor{  return null;}public int weight(){ return0;}}public class BasicBounds{ public static void main(String[] args){  Solid<Bounded> solid = new Solid<Bounded>(new Bounded());  lor();  X();  Y();  Z();  solid.weight();}}
Java泛型编程中使⽤extends关键字指定泛型参数类型的上边界(后⾯还会讲到使⽤super关键字指定泛型的下边界),即泛型只能适⽤于extends关键字后⾯类或接⼝的⼦类。
Java泛型编程的边界可以是多个,使⽤如<T extends A & B & C>语法来声明,其中只能有⼀个是类,并且只能是extends后⾯的第⼀个为类,其他的均只能为接⼝(和类/接⼝中的extends意义不同)。
使⽤了泛型边界之后,泛型对象就可以使⽤边界对象中公共的成员变量和⽅法。
2.泛型通配符:
泛型初始化过程中,⼀旦给定了参数类型之后,参数类型就会被限制,⽆法随着复制的类型⽽动态改变,如:
[java]
1. class Fruit{
2. }
3. class  extends Fruit{
4. }
5. class Jonathan extends Apple{
6. }
7. class Orange extends Fruit{
8. }
9. 如果使⽤数组:
10. public class ConvariantArrays{
11.    Fruit fruit = new Apple[10];
12.    Fruit[0] = new Apple();
13.    Fruit[1] = new Jonathan();
14.    try{
15.        fruit[0] = new Fruit();
16. }catch(Exception e){
17.    System.out.println(e);
18. }
19. try{
20.        fruit[0] = new Orange();
21. }catch(Exception e){
22.    System.out.println(e);
23. }
24. }
class Fruit{}class Apple extends Fruit{}class Jonathan extends Apple{}class Orange extends Fruit{}如果使⽤数组:public class ConvariantArrays{ Fruit fr uit = new Apple[10]; Fruit[0] = new Apple(); Fruit[1] = new Jonathan(); try{  fruit[0] = new Fruit();}catch(Exception e){ System.out.println(e);}try{  fruit[0] = new Orange();}catch(Exception e){ System.out.println(e);}}
编译时没有任何错误,运⾏时会报如下异常:
java.lang.ArrayStoreException:Fruit
java.lang.ArrayStoreException:Orange
为了使得泛型在编译时就可以进⾏参数类型检查,我们推荐使⽤java的集合容器类,如下:
[java]
1. public class NonConvariantGenerics{
2.    List<Fruit> flist = new ArrayList<Apple>();
3. }
public class NonConvariantGenerics{ List<Fruit> flist = new ArrayList<Apple>();}
很不幸的是,这段代码会报编译错误:incompatible types,不兼容的参数类型,集合认为虽然Apple继承⾃Fruit,但是List的Fruit和List的Apple是不相同的,因为泛型参数在声明时给定之后就被限制了,⽆法随着具体的初始化实例⽽动态改变,为解决这个问题,泛型引⼊了通配符”?”。
对于这个问题的解决,使⽤通配符如下:
[java]
1. public class NonConvariantGenerics{
2.    List<? extends Fruit> flist = new ArrayList<Apple>();
3. }
public class NonConvariantGenerics{ List<? extends Fruit> flist = new ArrayList<Apple>();}
韩国考驾照泛型通配符”?”的意思是任何特定继承Fruit的类,java编译器在编译时会根据具体的类型实例化。
另外,⼀个⽐较经典泛型通配符的例⼦如下:
public class SampleClass < T extendsS> {…}
假如A,B,C,…Z这26个class都实现了S接⼝。我们使⽤时需要使⽤到这26个class类型的泛型参数。那实例化的时候怎么办呢?依次写下
SampleClass<A> a = new SampleClass();
SampleClass<B> a = new SampleClass();
SampleClass<Z> a = new SampleClass();
这显然很冗余,还不如使⽤Object⽽不使⽤泛型,使⽤通配符⾮常⽅便:
兰德酷路泽4000报价SampleClass<? Extends S> sc = newSampleClass();
3.泛型下边界:
在1中⼤概了解了泛型上边界,使⽤extends关键字指定泛型实例化参数只能是指定类的⼦类,在泛型中还可以指定参数的下边界,是⼀super关键字可以指定泛型实例化时的参数只能是指定类的⽗类。
例如: