泛型类
——代码参考:java核心技术 卷1 第十版
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public
class
Pair<T>
{
private
T first;
private
T second;
//构造器
public
Pair() { first =
null
; second =
null
;}
public
Pair(T first , T second ) {
this
.first = first;
this
.second = second;}
//get方法
public
T getFirst() {
return
first; }
public
T getSecond () {
return
second;}
//set方法
public
void
setFirst(T newValue) { first =newValue; }
public
void
setSecond (T newValue) { second = newValue; }
}
|
泛型方法
1
2
3
4
5
|
class
A
public
static
<T> T get(T a)
{
return
a;
}
|
泛型方法可以定义在普通类中,也可定义在泛型类中。
类型擦除(Type Erasure)
以下内容参考自—— [Java泛型与桥方法]
JVM并不知道泛型的存在,因为泛型在编译阶段就已经被处理成普通的类和方法; 处理机制是通过类型擦除,擦除规则:
- 若泛型类型没有指定具体类型,用Object作为原始类型;
- 若有限定类型< T exnteds XClass >,使用XClass作为原始类型;
- 若有多个限定< T exnteds XClass1 & XClass2 >,使用第一个边界类型XClass1作为原始类型;
例如:上述泛型类Pair编译后的结果为
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public
class
Pair
{
private
Object first=
null
;
private
Object second=
null
;
public
Pair(Object fir,Object sec)
{
this
.first=fir;
this
.second=sec;
}
public
Object getFirst()
{
return
this
.first;
}
public
void
setFirst(Object fir)
{
this
.first=fir;
}
}
|
类型擦擦会带来一些问题,比如当一个类实现了一个参数化的接口或是继承了一个参数化的类时。
1
2
3
4
|
class
SonPair
extends
Pair<String>
//继承类一个泛型类
{
public
void
setFirst(String fir){....}
//重写了父类的方法
}
|
Pair在编译的时候已经被类型擦除,Pair的setFirst方法变为了setFirst(Object fir),这样SonPair的setFirst(Stirng fir)方法就无法覆盖父类中的setFirst(Object fir)方法,因为参数不同,不是同一个方法。 如下所示,SonPair中会出现两个方法:
1
2
|
public
void
setFirst(String fir){....}
public
void
setFirst(Object fir){....}
|
那么具体应该调用哪一个方法呢? 为了解决这个问题,jvm引进了桥方法的概念
桥方法
上一节中的两个方法被编译器变成了这样:
1
2
3
4
5
6
7
|
public
void
setFirst(String fir){....}
//这里什么都不变
//为该方法添加了一些东西,该方法就被称为“桥方法”
public
void
setFirst(Object fir)
{
setFirst((String) fir);
//桥内部调用的是子类中定义的setFirst(String fir)方法
}
|