协变和逆变指的是宽类型和窄类型在某种情况下的替换或交换的特性。简单的说,协变就是用一个窄类型替代宽类型,而逆变则用宽类型覆盖窄类型。
1 协变
在Java中协变的例子非常常见,例如,面向对象的多态,以及数组的协变特性,下面看一下协变的例子:
1
2
3
4
5
6
7
8
|
public
class
Test
{
public
static
void
main
(
String
[
]
args
)
{
Number
num1
=
new
Integer
(
0
)
;
Number
[
]
num2
=
new
Integer
[
10
]
;
}
}
|
而在泛型是不支持协变的,看下面的代码:
1
2
3
4
5
6
7
8
|
public
class
Test
{
public
static
void
main
(
String
[
]
args
)
{
List
<
Object
>
list
=
new
ArrayList
<
String
>
(
)
;
//编译错误
list
=
new
ArrayList
<
Object
>
(
)
;
}
}
|
虽然泛型不支持协变的,但是可以通过通配符进行模拟:
1
2
3
4
5
6
7
|
public
class
Test
{
public
static
void
main
(
String
[
]
args
)
{
List
<
?
extends
Object
>
list
=
new
ArrayList
<
String
>
(
)
;
}
}
|
注意:? extends Object的含义是:运行Object的子类,也包括Object,作为泛型参数。
2 逆变
在Java中不允许将父类变量赋值给子类变量。泛型自然也不支持逆变。但是在泛型中可以通过通配符进行模拟,如下例子:
1
2
3
4
5
6
7
|
public
class
Test
{
public
static
void
main
(
String
[
]
args
)
{
List
<
?
super
Integer
>
list
=
new
ArrayList
<
Number
>
(
)
;
}
}
|