java泛型extends多个
1.泛型边界:
例如:
[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关键字可以指定泛型实例化时的参数只能是指定类的⽗类。
例如:
发布评论