本篇內(nèi)容主要講解“jdk1.4和jdk1.5有什么區(qū)別”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“jdk1.4和jdk1.5有什么區(qū)別”吧!
成都創(chuàng)新互聯(lián)從2013年成立,是專(zhuān)業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì)網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元大同做網(wǎng)站,已為上家服務(wù),為大同各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話(huà):028-869222201. 泛型
2 自動(dòng)裝箱/拆箱
3 for-each
4 static import
5 變長(zhǎng)參數(shù)[@more@]
1. 泛型 1.4之前 java util包中容器類(lèi),裝的是Object對(duì)象,你要裝特定的類(lèi)型可以,但要強(qiáng)制轉(zhuǎn)換,這可能導(dǎo)致運(yùn)行時(shí)錯(cuò)誤.
例:原來(lái)ArrayList list=new ArrayList();
list.add(new Integer(3));
list.add(new Integer(4));
int i=((Integer)(list.get(0))).parseInt();
很麻煩
現(xiàn)在A(yíng)rrayList
list.add(new Integer(3));
list.add(new Integer(4));
int i=list.get(0).parseInt();
不用Cast,運(yùn)行時(shí)錯(cuò)誤變?yōu)榫幾g時(shí)錯(cuò)誤,這是進(jìn)步.
類(lèi)似與C++中的摸板templete.但機(jī)理不同.
2 自動(dòng)裝箱/拆箱
還是剛才例子
最后一句可改為
int i=list.get(0);
原始類(lèi)型與對(duì)應(yīng)的包裝類(lèi)不用顯式轉(zhuǎn)換,方便
3 for-each
循環(huán)的增強(qiáng)
int a[]={........};//初始化,略
for(int i:a)
{
......
}
不用以前的i=0;i4 static import
以前調(diào)Java.math
Math.sqrt();
現(xiàn)在 static import java.lang.Math.sqrt;
再 sqrt();
相當(dāng)于你自己類(lèi)里有這個(gè)方法
5 變長(zhǎng)參數(shù)
int sum(int ...intlist)
{
int i,sum;
sum=0;
for(int i=0;i
sum+=list[i];
}
return sum;
}
有任意個(gè)參數(shù),把他看作數(shù)組
沒(méi)多大區(qū)別,只要你注意別用那些過(guò)時(shí)的方法就行,若是新版本加的或有改變的方法,docs里會(huì)說(shuō)的,在方法解釋下面
jdk6.0將會(huì)有很大變化
增強(qiáng)的for循環(huán)
為了迭代集合和數(shù)組,增強(qiáng)的for循環(huán)提供了一個(gè)簡(jiǎn)單、兼容的語(yǔ)法。有兩點(diǎn)值得一提:
Init表達(dá)式
在循環(huán)中,初始化表達(dá)式只計(jì)算一次。這意味著您通常可以移除一個(gè)變量聲明。在這個(gè)例子中,我們必須創(chuàng)建一個(gè)整型數(shù)組來(lái)保存computeNumbers()的結(jié)果,以防止每一次循環(huán)都重新計(jì)算該方法。您可以看到,下面的代碼要比上面的代碼整潔一些,并且沒(méi)有泄露變量numbers:
未增強(qiáng)的For:
int sum = 0;
Integer[] numbers = computeNumbers();
for (int i=0; i < numbers.length ; i++)
sum += numbers[i];
增強(qiáng)后的For:
int sum = 0;
for ( int number: computeNumbers() )
sum += number;
局限性
有時(shí)需要在迭代期間訪(fǎng)問(wèn)迭代器或下標(biāo),看起來(lái)增強(qiáng)的for循環(huán)應(yīng)該允許該操作,但事實(shí)上不是這樣,請(qǐng)看下面的例子:
for (int i=0; i < numbers.length ; i++) {
if (i != 0) System.out.print(",");
System.out.print(numbers[i]);
}
我們希望將數(shù)組中的值打印為一個(gè)用逗號(hào)分隔的清單。我們需要知道目前是否是第一項(xiàng),以便確定是否應(yīng)該打印逗號(hào)。使用增強(qiáng)的for循環(huán)是無(wú)法獲知這種信息的。我們需要自己保留一個(gè)下標(biāo)或一個(gè)布爾值來(lái)指示是否經(jīng)過(guò)了第一項(xiàng)。 這是另一個(gè)例子:
for (Iterator
if (it.next() < 0)
it.remove();
在此例中,我們想從整數(shù)集合中刪除負(fù)數(shù)項(xiàng)。為此,需要對(duì)迭代器調(diào)用一個(gè)方法,但是當(dāng)使用增強(qiáng)的for 循環(huán)時(shí),迭代器對(duì)我們來(lái)說(shuō)是看不到的。因此,我們只能使用Java 5之前版本的迭代方法。 順便說(shuō)一下,這里需要注意的是,由于Iterator是泛型,所以其聲明是Iterator
注釋
注釋處理是一個(gè)很大的話(huà)題。因?yàn)楸疚闹魂P(guān)注核心的語(yǔ)言特性,所以我們不打算涵蓋它所有的可能形式和陷阱。 我們將討論內(nèi)置的注釋?zhuān)⊿uppressWarnings,Deprecated和Override)以及一般注釋處理的局限性。
Suppress Warnings
該注釋關(guān)閉了類(lèi)或方法級(jí)別的編譯器警告。有時(shí)候您比編譯器更清楚地知道,代碼必須使用一個(gè)被否決的方法或執(zhí)行一些無(wú)法靜態(tài)確定是否類(lèi)型安全的動(dòng)作,而使用:
@SuppressWarnings("deprecation")
public static void selfDestruct() {
Thread.currentThread().stop();
}
這可能是內(nèi)置注釋最有用的地方。遺憾的是,1.5.0_04的javac不支持它。但是1.6支持它,并且Sun正在努力將其向后移植到1.5中。
Eclipse 3.1中支持該注釋?zhuān)渌鸌DE也可能支持它。這允許您把代碼徹底地從警告中解脫出來(lái)。如果在編譯時(shí)出現(xiàn)警告,可以確定是您剛剛把它添加進(jìn)來(lái)——以幫助查看那些可能不安全的代碼。隨著泛型的添加,它使用起來(lái)將更趁手。
Deprecated
遺憾的是,Deprecated沒(méi)那么有用。它本來(lái)旨在替換@deprecated javadoc標(biāo)簽,但是由于它不包含任何字段,所以也就沒(méi)有方法來(lái)建議deprecated類(lèi)或方法的用戶(hù)應(yīng)該使用什么做為替代品。大多數(shù)用法都同時(shí)需要javadoc標(biāo)簽和這個(gè)注釋。
Override
Override表示,它所注釋的方法應(yīng)該重寫(xiě)超類(lèi)中具有相同簽名的方法:
@Override
public int hashCode() {
...
}
看上面的例子,如果沒(méi)有在hashCode中將“C”大寫(xiě),在編譯時(shí)不會(huì)出現(xiàn)錯(cuò)誤,但是在運(yùn)行時(shí)將無(wú)法像期望的那樣調(diào)用該方法。通過(guò)添加Override標(biāo)簽,編譯器會(huì)提示它是否真正地執(zhí)行了重寫(xiě)。
在超類(lèi)發(fā)生改變的情況中,這也很有幫助。如果向該方法中添加一個(gè)新參數(shù),而且方法本身也被重命名了,那么子類(lèi)將突然不能編譯,因?yàn)樗辉僦貙?xiě)超類(lèi)的任何東西。
其它注釋
注釋在其他場(chǎng)景中非常有用。當(dāng)不是直接修改行為而是增強(qiáng)行為時(shí),特別是在添加樣板代碼的情況下,注釋在諸如EJB和Web services這樣的框架中運(yùn)行得非常好。
注釋不能用做預(yù)處理器。Sun的設(shè)計(jì)特別預(yù)防了完全因?yàn)樽⑨尪薷念?lèi)的字節(jié)碼。這樣可以正確地理解該語(yǔ)言的成果,而且IDE之類(lèi)的工具也可以執(zhí)行深入的代碼分析和重構(gòu)之類(lèi)的功能。
注釋不是銀彈。第一次遇到的時(shí)候,人們?cè)噲D嘗試各種技巧。請(qǐng)看下面這個(gè)從別人那里獲得的建議:
public class Foo {
@Property
private int bar;
}
其思想是為私有字段bar自動(dòng)創(chuàng)建getter和setter方法。遺憾的是,這個(gè)想法有兩個(gè)失敗之處:1)它不能運(yùn)行,2)它使代碼難以閱讀和處理。 它是無(wú)法實(shí)現(xiàn)的,因?yàn)榍懊嬉呀?jīng)提到了,Sun特別阻止了對(duì)出現(xiàn)注釋的類(lèi)進(jìn)行修改。
即使是可能的,它也不是一個(gè)好主意,因?yàn)樗勾a可讀性差。第一次看到這段代碼的人會(huì)不知道該注釋創(chuàng)建了方法。此外,如果將來(lái)您需要在這些方法內(nèi)部執(zhí)行一些操作,注釋也是沒(méi)用的。 總之,不要試圖用注釋去做那些常規(guī)代碼可以完成的事情。
枚舉
enum非常像public static final int聲明,后者作為枚舉值已經(jīng)使用了很多年。對(duì)int所做的大也是最明顯的改進(jìn)是類(lèi)型安全——您不能錯(cuò)誤地用枚舉的一種類(lèi)型代替另一種類(lèi)型,這一點(diǎn)和int不同,所有的int對(duì)編譯器來(lái)說(shuō)都是一樣的。除去極少數(shù)例外的情況,通常都應(yīng)該用enum實(shí)例替換全部的枚舉風(fēng)格的int結(jié)構(gòu)。
枚舉提供了一些附加的特性。EnumMap和EnumSet這兩個(gè)實(shí)用類(lèi)是專(zhuān)門(mén)為枚舉優(yōu)化的標(biāo)準(zhǔn)集合實(shí)現(xiàn)。如果知道集合只包含枚舉類(lèi)型,那么應(yīng)該使用這些專(zhuān)門(mén)的集合來(lái)代替HashMap或HashSet。
大部分情況下,可以使用enum對(duì)代碼中的所有public static final int做插入替換。它們是可比的,并且可以靜態(tài)導(dǎo)入,所以對(duì)它們的引用看起來(lái)是等同的,即使是對(duì)于內(nèi)部類(lèi)(或內(nèi)部枚舉類(lèi)型)。注意,比較枚舉類(lèi)型的時(shí)候,聲明它們的指令表明了它們的順序值。
“隱藏的”靜態(tài)方法
兩個(gè)靜態(tài)方法出現(xiàn)在所有枚舉類(lèi)型聲明中。因?yàn)樗鼈兪敲杜e子類(lèi)上的靜態(tài)方法,而不是Enum本身的方法,所以它們?cè)趈ava.lang.Enum的javadoc中沒(méi)有出現(xiàn)。
第一個(gè)是values(),返回一個(gè)枚舉類(lèi)型所有可能值的數(shù)組。
第二個(gè)是valueOf(),為提供的字符串返回一個(gè)枚舉類(lèi)型,該枚舉類(lèi)型必須精確地匹配源代碼聲明。
方法
關(guān)于枚舉類(lèi)型,我們最喜歡的一個(gè)方面是它可以有方法。過(guò)去您可能需要編寫(xiě)一些代碼,對(duì)public static final int進(jìn)行轉(zhuǎn)換,把它從數(shù)據(jù)庫(kù)類(lèi)型轉(zhuǎn)換為JDBC URL。而現(xiàn)在則可以讓枚舉類(lèi)型本身帶一個(gè)整理代碼的方法。下面就是一個(gè)例子,包括DatabaseType枚舉類(lèi)型的抽象方法以及每個(gè)枚舉實(shí)例中提供的實(shí)現(xiàn):
public enum DatabaseType {
ORACLE {
public String getJdbcUrl() {...}
},
MYSQL {
public String getJdbcUrl() {...}
};
public abstract String getJdbcUrl();
}
現(xiàn)在枚舉類(lèi)型可以直接提供它的實(shí)用方法。例如:
DatabaseType dbType = ...;
String jdbcURL = dbType.getJdbcUrl();
要獲取URL,必須預(yù)先知道該實(shí)用方法在哪里。
可變參數(shù)(Vararg)
正確地使用可變參數(shù)確實(shí)可以清理一些垃圾代碼。典型的例子是一個(gè)帶有可變的String參數(shù)個(gè)數(shù)的log方法:
Log.log(String code)
Log.log(String code, String arg)
Log.log(String code, String arg1, String arg2)
Log.log(String code, String[] args)
當(dāng)討論可變參數(shù)時(shí),比較有趣的是,如果用新的可變參數(shù)替換前四個(gè)例子,將是兼容的:
Log.log(String code, String... args)
所有的可變參數(shù)都是源兼容的——那就是說(shuō),如果重新編譯log()方法的所有調(diào)用程序,可以直接替換全部的四個(gè)方法。然而,如果需要向后的二進(jìn)制兼容性,那么就需要舍去前三個(gè)方法。只有最后那個(gè)帶一個(gè)字符串?dāng)?shù)組參數(shù)的方法等效于可變參數(shù)版本,因此可以被可變參數(shù)版本替換。
類(lèi)型強(qiáng)制轉(zhuǎn)換
如果希望調(diào)用程序了解應(yīng)該使用哪種類(lèi)型的參數(shù),那么應(yīng)該避免用可變參數(shù)進(jìn)行類(lèi)型強(qiáng)制轉(zhuǎn)換。看下面這個(gè)例子,第一項(xiàng)希望是String,第二項(xiàng)希望是Exception:
Log.log(Object... objects) {
String message = (String)objects[0];
if (objects.length > 1) {
Exception e = (Exception)objects[1];
// Do something with the exception
}
}
方法簽名應(yīng)該如下所示,相應(yīng)的可變參數(shù)分別使用String和Exception聲明:
Log.log(String message, Exception e, Object... objects) {...}
不要使用可變參數(shù)破壞類(lèi)型系統(tǒng)。需要強(qiáng)類(lèi)型化時(shí)才可以使用它。對(duì)于這個(gè)規(guī)則,PrintStream.printf()是一個(gè)有趣的例外:它提供類(lèi)型信息作為自己的第一個(gè)參數(shù),以便稍后可以接受那些類(lèi)型。
協(xié)變返回
協(xié)變返回的基本用法是用于在已知一個(gè)實(shí)現(xiàn)的返回類(lèi)型比API更具體的時(shí)候避免進(jìn)行類(lèi)型強(qiáng)制轉(zhuǎn)換。在下面這個(gè)例子中,有一個(gè)返回Animal對(duì)象的Zoo接口。我們的實(shí)現(xiàn)返回一個(gè)AnimalImpl對(duì)象,但是在JDK 1.5之前,要返回一個(gè)Animal對(duì)象就必須聲明。:
public interface Zoo {
public Animal getAnimal();
}
public class ZooImpl implements Zoo {
public Animal getAnimal(){
return new AnimalImpl();
}
}
協(xié)變返回的使用替換了三個(gè)反模式:
直接字段訪(fǎng)問(wèn)。為了規(guī)避API限制,一些實(shí)現(xiàn)把子類(lèi)直接暴露為字段:
ZooImpl._animal
另一種形式是,在知道實(shí)現(xiàn)的實(shí)際上是特定的子類(lèi)的情況下,在調(diào)用程序中執(zhí)行向下轉(zhuǎn)換:
((AnimalImpl)ZooImpl.getAnimal()).implMethod();
我看到的最后一種形式是一個(gè)具體的方法,該方法用來(lái)避免由一個(gè)完全不同的簽名所引發(fā)的問(wèn)題:
ZooImpl._getAnimal();
這三種模式都有它們的問(wèn)題和局限性。要么是不夠整潔,要么就是暴露了不必要的實(shí)現(xiàn)細(xì)節(jié)。
協(xié)變
協(xié)變返回模式就比較整潔、安全并且易于維護(hù),它也不需要類(lèi)型強(qiáng)制轉(zhuǎn)換或特定的方法或字段:
public AnimalImpl getAnimal(){
return new AnimalImpl();
}
使用結(jié)果:
ZooImpl.getAnimal().implMethod();
使用泛型
我們將從兩個(gè)角度來(lái)了解泛型:使用泛型和構(gòu)造泛型。我們不討論List、Set和Map的顯而易見(jiàn)的用法。知道泛型集合是強(qiáng)大的并且應(yīng)該經(jīng)常使用就足夠了。
我們將討論泛型方法的使用以及編譯器推斷類(lèi)型的方法。通常這些都不會(huì)出問(wèn)題,但是當(dāng)出問(wèn)題時(shí),錯(cuò)誤信息會(huì)非常令人費(fèi)解,所以需要了解如何修復(fù)這些問(wèn)題。
泛型方法
除了泛型類(lèi)型,Java 5還引入了泛型方法。在這個(gè)來(lái)自java.util.Collections的例子中,構(gòu)造了一個(gè)單元素列表。新的List的元素類(lèi)型是根據(jù)傳入方法的對(duì)象的類(lèi)型來(lái)推斷的:
static
示例用法:
public List
return Collections.singletonList(1);
}
在示例用法中,我們傳入了一個(gè)int。所以方法的返回類(lèi)型就是List
這也顯示了自動(dòng)裝箱和泛型的相互作用。類(lèi)型參數(shù)必須是引用類(lèi)型:這就是為什么我們得到的是List
不帶參數(shù)的泛型方法
emptyList()方法與泛型一起引入,作為java.util.Collections中EMPTY_LIST字段的類(lèi)型安全置換:
static
示例用法:
public List
return Collections.emptyList();
}
與先前的例子不同,這個(gè)方法沒(méi)有參數(shù),那么編譯器如何推斷T的類(lèi)型呢?基本上,它將嘗試使用一次參數(shù)。如果沒(méi)有起作用,它再次嘗試使用返回或賦值類(lèi)型。在本例中,返回的是List
如果在返回語(yǔ)句或賦值語(yǔ)句之外的位置調(diào)用泛型方法會(huì)怎么樣呢?那么編譯器將無(wú)法執(zhí)行類(lèi)型推斷的第二次傳送。在下面這個(gè)例子中,emptyList()是從條件運(yùn)算符內(nèi)部調(diào)用的:
public List
return x ? Collections.emptyList() : null;
}
因?yàn)榫幾g器看不到返回上下文,也不能推斷T,所以它放棄并采用Object。您將看到一個(gè)錯(cuò)誤消息,比如:“無(wú)法將List
到此,相信大家對(duì)“jdk1.4和jdk1.5有什么區(qū)別”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢(xún),關(guān)注我們,繼續(xù)學(xué)習(xí)!