//是這樣嗎?
創(chuàng)新互聯(lián)長期為千余家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊從業(yè)經(jīng)驗10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為北海企業(yè)提供專業(yè)的網(wǎng)站設(shè)計制作、成都網(wǎng)站制作,北海網(wǎng)站改版等技術(shù)服務(wù)。擁有十載豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。
public class FTestDraw {
public static void main(String[] args) {
DrawMethodShape dm = new DrawMethodShape(new Circle());
dm.shape.draw();
}
}
abstract class Shape{
abstract void draw();
}
class Circle extends Shape{
@Override
void draw() {
System.out.println("這是圓形");
}
}
class Rectangle extends Shape{
@Override
void draw(){
System.out.println("這是長方形");
}
}
class Triangle extends Shape{
@Override
void draw(){
System.out.println("這是三角形");
}
}
class DrawMethodT extends Shape{
T shape = null;
public DrawMethod(T tt){
shape = tt;
}
}
您好,我用斷點調(diào)試解釋吧[真的很高興能與你討論][啊啦上回不好意思但還是說對一部分滴].
1-----你在go方法中,沒有給list限制泛型約束,所以1.1不加check的存儲進(jìn)arraylist了.
2-----"1.1"是被內(nèi)部機(jī)制轉(zhuǎn)換為Double存儲進(jìn)arraylist的:
[在System.out.println(list.get(1));處下斷點,點調(diào)試.可以看到list里是
[1, 1.1],
elementData[]為
[1, 1.1, null, null, null, null, null, null, null, null].
elementData[0]的值是"1",
elementData[1]的值為Double (標(biāo)識=37).]
也就是說,go方法add時因為沒有約束,所以由內(nèi)部機(jī)制將1.1轉(zhuǎn)換為Double存入了以String為約束的list里.
3-----點"單步跳入",看到代碼跳到了arraylist的get里:
public E get(int index) {
RangeCheck(index);
return elementData[index];
}
關(guān)鍵點就在這了,由第2步看到elementData[1]的類型為Double,而在main里為list設(shè)置的約束是String,所以E 為String.上面的代碼就變?yōu)?
public String get(int index) {
RangeCheck(index);
return 1.1; //double
}
繼續(xù)跳,
看到他照樣返回了一個加著String標(biāo)簽的double值.
4-----繼續(xù)點然后報錯了.這個是由于syso輸出是輸出String.這個后面會說.
如果你加一個方法:
public static void go1(List list)
{
System.out.println(list.get(1));
}
這樣沒約束的情況下syso,是沒有錯的.因為get后的對象沒有加類型標(biāo)簽,會由內(nèi)部機(jī)制判斷他到底是哪個類.
而加了String返回類型標(biāo)簽后就不做判斷直接調(diào)用syso(String)的方法來輸出Double了.所以報告了class cast錯誤.
如果你繼續(xù)看,會看到是String類的init出現(xiàn)的錯誤.
因為前面調(diào)試中看到syso(args)的args為String[],而返回的卻是Double.類型沒匹配上.
正確的那個例子不用說了吧,調(diào)試一下會發(fā)現(xiàn)他syso時String.valueof(obj)了,"1.1"肯定滿足條件.[如果不滿足條件,會打印object,這也是能輸出syso(list)的原因][SYSO在控制臺輸出的是字符,如果是double會轉(zhuǎn)為字符輸出]
而錯的那個因為返回標(biāo)明了是String,所以程序不加判斷就直接write了,輸出字符卻給個double,就出錯了.
上班了...打一中午,555,可能說的有錯誤,樓主自己調(diào)試一下,以自己的方式理解一下吧_
PS:其實俺上回說的有一部分對...我樓上那位5級大哥說的也部分對,但1.1是double傳進(jìn)去的,沒轉(zhuǎn)換成int.調(diào)試過我就明白了,一開始我也那么想.
1.1 list.get()返回類型為?,所以你只能用Object接收,Object足以確保type-safe,因為java中任何class都是Object的subclass。(當(dāng)然,如果你非要使用類型強(qiáng)制轉(zhuǎn)換,轉(zhuǎn)換成什么阿貓阿狗的class,也沒人攔得住你,對此只能說“編譯器盡力了,你行你上啊”,反正ClassCastException什么的最有愛了)
2.2 list.put()除了null以外,任何參數(shù)都不接收。這也足以確保list中類型的type-safe,要知道,java的泛型的implementation是基于ERASURE(擦除)的,舉個具體的例子,LinkedListE的內(nèi)部數(shù)據(jù)結(jié)構(gòu)肯定是基于NodeE,那么一個Node有2個field,E element和NodeE next,而實際上在runtime環(huán)境中,LinkedListString中的Node并不是NodeString,僅僅是Node,Node里面的element的類型也不是String,僅僅是Object,也就是說,compile-time的type-information都被抹除了(Quote: For backward-compatibility)。試想這么一個情景,Tom傳了一個ListDog給Mike,Mike的interface是List?,Mike往list中放了一個Cat(假設(shè)compiler沒有阻止Mike),然后Tom取出該List中所有的object并當(dāng)成Dog使用(compiler會自動加上類型轉(zhuǎn)換的代碼——which is how java generics worked),然后Tom就悲劇地得到了一個ClassCastException——這就是為什么除了null其他參數(shù)都不接收的原因——阻止Mike隨便放東西進(jìn)去。
2、List
raw-type就是這么個情況,相當(dāng)于你對compiler說:“我并不在乎這個List里面的element的runtime-type是什么,不管我怎么操作這個list或者list中取出來的object,你都別管,實在看不過去就給我個warning就行了”。這種情況下:
2.1 list.get()返回類型為Object,當(dāng)然,也是type-safe的(如果你不強(qiáng)制轉(zhuǎn)換的話)
2.2 list.put()的參數(shù)類型為Object,也就是說,你愛往里面放什么object就放什么object,還是上面那個例子,就算Tom給Mike的是ListString,但由于Mike的interface是List,所以Mike放個BigInteger甚至什么Cat、Dog,compiler都不會阻止Mike(但是,要知道,Mike是無法得知其他人會怎么使用這個List的,比如說Mike無法得知Tom相信編譯器確保了list中的object都是String,但是由于Mike的raw-type interface,Tom就難免吃ClassCastException咯)
名稱欄目:java泛型list代碼,java list泛型集合
轉(zhuǎn)載來于:http://chinadenli.net/article18/hecggp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供營銷型網(wǎng)站建設(shè)、電子商務(wù)、小程序開發(fā)、網(wǎng)站策劃、微信小程序、網(wǎng)站維護(hù)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)