- 转自:http://my.oschina.net/u/1386903/blog/173726
-
- 1:Java的泛型是类型擦除的。
- 2:不能初始化泛型参数和数组
- 3:不同场景使用不同的泛型通配符
- 4:建议使用顺序:List,List,List
- 4:只有上限由多重限定&,下限没有
- 5:不能在静态域或方法中引用类型变量
1:Java的泛型是类型擦除的。
java的泛型在编译期有效,但是在运行期所有的类型参数都会被删除。
1
class
example{
2
public
void
arrayMethod(String[] strArray){}
3
public
void
arraymethod(Integer[] intArray){}
4
public
void
listMethod(List<String> strList){}
5
public
void
listMethod(List<Integer> intList){}
6
}
JAVA泛型在编译期,所有泛型类型都会转换,编译后的字节码是没有任何泛型信息的,也就是说:一个泛型类和一个普通类在编译后指向同一个字节码。这样做的原因:
1:泛型只存在编译期,而不在运行期,避免了JVM的大换血
2:版本兼容,在1.5以上的版本中,List这样的 原生类型也可以正常编译通过,只是会出现警告而已。
因为泛型是类型擦除的,所以:
1:泛型的class对象是相同的,每个类都有class属性,泛型化不会改变其返回值
1
class
example2 {
2
public
void
test() {
3
List<String> list1 =
new
ArrayList<String>();
4
List<Integer> list2 =
new
ArrayList<Integer>();
5
System.out.println(list1.getClass() == list2.getClass());
6
}
7
}
1
// List<String>[] strList;
2
List<String>[] strList =
new
List<String>[];
3:instanceof不允许存在泛型参数
2:不能初始化泛型参数和数组
3:不同场景使用不同的泛型通配符
1:泛型结构只参与”读“的操作,则限定上限(extends关键字)
1
public
static
<E>
void
read(List<?
extends
E> list){
2
for
(E e : list) {
3
//业务操作
4
}
5
}
可以推断出List中取出的是E类型的,具体类型在运行时才能确定,但是一定是一个确定的类型。
2:泛型结构只参与”写“的操作,则限定下限(super 关键字)
1
public
static
void
write(List<?
super
Number> list){
2
list.add(
23
);
3
list.add(
12.34
);
4
}
JDK中的一个例子Collections.copy方法来说明上限跟下限,它实现了把源列表中的所有元素拷贝到目标列表中对应的索引处。
01
public
static
<T>
void
copy(List<?
super
T> dest, List<?
extends
T> src) {
02
int
srcSize = src.size();
03
if
(srcSize > dest.size())
04
throw
new
IndexOutOfBoundsException(
"Source does not fit in dest"
);
05
06
if
(srcSize < COPY_THRESHOLD ||
07
(src
instanceof
RandomAccess && dest
instanceof
RandomAccess)) {
08
for
(
int
i=
0
; i<srcSize; i++)
09
dest.set(i, src.get(i));
10
}
else
{
11
ListIterator<?
super
T> di=dest.listIterator();
12
ListIterator<?
extends
T> si=src.listIterator();
13
for
(
int
i=
0
; i<srcSize; i++) {
14
di.next();
15
di.set(si.next());
16
}
17
}
18
}
源列表是用来提供数据的,所以src要用extends,目标列表是用来写入数据的,所以dest需要用super
如果既要读又要写,那么只需要用确定的泛型类型即可,如List<E>.
4:建议使用顺序:List<T>,List<?>,List<Object>
1:List<T>是一个确定的类型,只不过是在运行期确定而已
2:List<T>可以进行读写操作, add,remove等操作,因为固定类型为T,所以不需要转型。List<?>只读类型,因为我不能确定你到底是什么类型 ,这样就不安全了,List<?>取出的是Object类型,需要主动转型
4:只有上限由多重限定&,下限没有
5:不能在静态域或方法中引用类型变量
1
<strong>
class
example3<T>{
2
private
static
T s;
3
public
static
void
method(T t){
4
// do method
5
}
6
}</strong>
总而言之:
1:虚拟机中没有泛型,只有普通的类和方法。
2:所有的类型参数都用他们的限定类型替换
3:桥方法被合成来保持多态
4:为保持类型安全,必要时插入强制类型转换。
一个泛型的实例
001
package
generic;
002
003
import
java.util.Date;
004
import
java.util.GregorianCalendar;
005
006
public
class
PairTest3 {
007
public
static
void
main(String[] args) {
008
Manager ceo =
new
Manager(
"Gus Greedy"
,
80000
,
2003
,
12
,
15
);
009
Manager cfo =
new
Manager(
"Sid sneaky"
,
60000
,
2003
,
12
,
15
);
010
Pair<Manager> buddies =
new
Pair<Manager>(ceo, cfo);
011
printBuddies(buddies);
012
013
ceo.setBonus(
100000
);
014
cfo.setBonus(
50000
);
015
Manager[] managers = { ceo, cfo };
016
Pair<Employee> result =
new
Pair<Employee>();
017
minmax(managers, result);
018
System.out.println(result.getFirst().getName()
019
+ result.getSecond().getName());
020
maxminBonus(managers, result);
021
System.out.println(result.getFirst().getName()
022
+ result.getSecond().getName());
023
}
024
025
public
static
void
printBuddies(Pair<?
extends
Employee> p) {
026
Employee first = p.getFirst();
027
Employee secend = p.getSecond();
028
System.out.println(first.getName() + secend.getName());
029
}
030
031
public
static
void
minmax(Manager[] a, Pair<?
super
Manager> result) {
032
if
(a ==
null
|| a.length ==
0
)
033
return
;
034
Manager min = a[
0
];
035
Manager max = a[
0
];
036
for
(
int
i =
0
; i < a.length; i++) {
037
if
(min.getBonus() > a[i].getBonus())
038
min = a[i];
039
if
(max.getBonus() < a[i].getBonus())
040
max = a[i];
041
}
042
result.setFirst(min);
043
result.setSecond(max);
044
}
045
046
public
static
void
maxminBonus(Manager[] a, Pair<?
super
Manager> result) {
047
minmax(a, result);
048
PairAlg.swapHelper(result);
049
}
050
}
051
052
class
PairAlg {
053
public
static
boolean
hasNulls(Pair<?> p) {
054
return
p.getFirst() ==
null
|| p.getSecond() ==
null
;
055
}
056
057
public
static
void
swap(Pair<?> p) {
058
swapHelper(p);
059
}
060
061
public
static
<T>
void
swapHelper(Pair<T> p) {
062
T t = p.getFirst();
063
p.setFirst(p.getSecond());
064
p.setSecond(t);
065
}
066
}
067
068
class
Employee {
069
private
String name;
070
private
double
salary;
071
private
Date hireDay;
072
073
public
Employee(String n,
double
s,
int
year,
int
month,
int
day) {
074
name = n;
075
salary = s;
076
GregorianCalendar calendar =
new
GregorianCalendar(year, month -
1
, day);
077
hireDay = calendar.getTime();
078
}
079
080
public
void
raiseSalary(
double
byPercent) {
081
double
raise = salary * byPercent;
082
salary += raise;
083
084
}
085
086
public
String getName() {
087
return
name;
088
}
089
090
public
double
getSalary() {
091
return
salary;
092
}
093
094
public
Date getHirDay() {
095
return
hireDay;
096
}
097
}
098
099
class
Manager
extends
Employee {
100
private
double
bonus;
101
102
public
Manager(String n,
double
s,
int
year,
int
month,
int
day) {
103
super
(n, s, year, month, day);
104
bonus =
0
;
105
}
106
107
public
double
getBonus() {
108
return
bonus;
109
}
110
111
public
void
setBonus(
double
bonus) {
112
this
.bonus = bonus;
113
}
114
115
public
double
getSalary() {
116
double
baseSalary =
super
.getSalary();
117
return
baseSalary + bonus;
118
}
119
120
}
关于泛型
最新推荐文章于 2022-11-12 15:29:55 发布