亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java編程之jdk1.4,jdk1.5和jdk1.6的區(qū)別分析(經(jīng)典)

 更新時(shí)間:2015年12月21日 14:49:11   作者:tanguang_honesty  
這篇文章主要介紹了Java編程之jdk1.4,jdk1.5和jdk1.6的區(qū)別分析,結(jié)合實(shí)例形式較為詳細(xì)的分析說明了jdk1.4,jdk1.5和jdk1.6版本的使用區(qū)別,需要的朋友可以參考下

本文結(jié)合實(shí)例詳細(xì)分析了Java編程之jdk1.4,jdk1.5和jdk1.6的區(qū)別。分享給大家供大家參考,具體如下:

簡(jiǎn)單說:1.4和1.5最大的區(qū)別有兩個(gè),一個(gè)是1.5有泛型,另一個(gè)1.5可以自動(dòng)封裝八大基本數(shù)據(jù)類型的封裝數(shù)據(jù)類型,即,Integer a = 4這個(gè)1.4是不可以的。1.5和1.6的區(qū)別不大。1.6我覺得最多的變化,我覺得最大的部分是在GUI上面,提供了很多方便的布局管理和擴(kuò)展。

這段時(shí)間進(jìn)了一家電子政務(wù)公司,都用weblogic8,那咱就用jdk1.4吧,eclipse一改jdk版本,這不以前的項(xiàng)目基本都一片紅了。

★jdk1.5的新特性:

1. 泛型
2 自動(dòng)裝箱/拆箱
3 for-each
4 static import
5 變長(zhǎng)參數(shù)

1. 泛型 (避免類型強(qiáng)制轉(zhuǎn)換可能引起的運(yùn)行錯(cuò)誤)

例如:

ArrayList list=new ArrayList(); 
list.add(new Integer(3)); 
list.add(new Integer(4)); 
int i=((Integer)(list.get(0))).parseInt(); 

很麻煩

ArrayList<Integer>list=new ArrayList<Integer>(); 
list.add(new Integer(3)); 
list.add(new Integer(4)); 
int i=list.get(0).parseInt();

2 自動(dòng)裝箱/拆箱

上面例子的最后一句可改為:

復(fù)制代碼 代碼如下:
int i=list.get(0);

因?yàn)樵碱愋团c對(duì)應(yīng)的包裝類不用顯式轉(zhuǎn)換

3 for-each

循環(huán)的增強(qiáng)

int a[]={........};//初始化 
for(int i:a) 
{ 
...... 
} 

不用以前的i=0;i<a.length;i++

4 static import

以前調(diào)Java.math

復(fù)制代碼 代碼如下:
Math.sqrt();

現(xiàn)在 static import java.lang.Math.sqrt;
再 sqrt();
相當(dāng)于你自己類里有這個(gè)方法

5 變長(zhǎng)參數(shù)

int sum(int ...intlist) 
{ 
int sum; 
sum=0; 
for(int i=0;i<intlist.length;i++) 
{ 
sum+=intlist[i]; 
} 
return sum;
} 

有任意個(gè)參數(shù),把他看作數(shù)組

★jdk6.0新特性

增強(qiáng)的for循環(huán)語(yǔ)句
注釋
枚舉
“隱藏的”靜態(tài)方法
可變參數(shù)(Vararg)
通配符和協(xié)變返回
增強(qiáng)的for循環(huán)語(yǔ)句

為了迭代集合和數(shù)組,增強(qiáng)的for循環(huán)提供了一個(gè)簡(jiǎn)單、兼容的語(yǔ)法。有兩點(diǎn)值得一提:

一、在循環(huán)中,初始化表達(dá)式只計(jì)算一次。int表達(dá)式

未增強(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;

局限性

增強(qiáng)的for循環(huán)迭代期間不能訪問迭代器或下標(biāo)

請(qǐng)看下面的例子:

for (int i=0; i < numbers.length ; i++) {
if (i != 0) System.out.print(",");
System.out.print(numbers[i]);
}

這是另一個(gè)例子:

for (Iterator<integer> it = n.iterator() ; it.hasNext() ; )
if (it.next() < 0)
it.remove();

注釋

注釋處理是一個(gè)很大的話題。因?yàn)楸疚闹魂P(guān)注核心的語(yǔ)言特性,所以我們不打算涵蓋它所有的可能形式和陷阱。 我們將討論內(nèi)置的注釋(SuppressWarnings,Deprecated和Override)以及一般注釋處理的局限性。

Suppress Warnings

該注釋關(guān)閉了類或方法級(jí)別的編譯器警告。有時(shí)候您比編譯器更清楚地知道,代碼必須使用一個(gè)被否決的方法或執(zhí)行一些無法靜態(tà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中支持該注釋,其他IDE也可能支持它。這允許您把代碼徹底地從警告中解脫出來。如果在編譯時(shí)出現(xiàn)警告,可以確定是您剛剛把它添加進(jìn)來——以幫助查看那些可能不安全的代碼。隨著泛型的添加,它使用起來將更趁手。

Deprecated

遺憾的是,Deprecated沒那么有用。它本來旨在替換@deprecated javadoc標(biāo)簽,但是由于它不包含任何字段,所以也就沒有方法來建議deprecated類或方法的用戶應(yīng)該使用什么做為替代品。大多數(shù)

用法都同時(shí)需要javadoc標(biāo)簽和這個(gè)注釋。

Override

Override表示,它所注釋的方法應(yīng)該重寫超類中具有相同簽名的方法:

@Override
public int hashCode() {
...
}

看上面的例子,如果沒有在hashCode中將“C”大寫,在編譯時(shí)不會(huì)出現(xiàn)錯(cuò)誤,但是在運(yùn)行時(shí)將無法像期望的那樣調(diào)用該方法。通過添加Override標(biāo)簽,編譯器會(huì)提示它是否真正地執(zhí)行了重寫。

在超類發(fā)生改變的情況中,這也很有幫助。如果向該方法中添加一個(gè)新參數(shù),而且方法本身也被重命名了,那么子類將突然不能編譯,因?yàn)樗辉僦貙懗惖娜魏螙|西。

其它注釋

注釋在其他場(chǎng)景中非常有用。當(dāng)不是直接修改行為而是增強(qiáng)行為時(shí),特別是在添加樣板代碼的情況下,注釋在諸如EJB和Web services這樣的框架中運(yùn)行得非常好。

注釋不能用做預(yù)處理器。Sun的設(shè)計(jì)特別預(yù)防了完全因?yàn)樽⑨尪薷念惖淖止?jié)碼。這樣可以正確地理解該語(yǔ)言的成果,而且IDE之類的工具也可以執(zhí)行深入的代碼分析和重構(gòu)之類的功能。

注釋不是銀彈。第一次遇到的時(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)它使代碼難以閱讀和處理。 它是無法實(shí)現(xiàn)的,因?yàn)榍懊嬉呀?jīng)提到了,Sun特別阻止了對(duì)出現(xiàn)注釋的類進(jìn)行修改。

即使是可能的,它也不是一個(gè)好主意,因?yàn)樗勾a可讀性差。第一次看到這段代碼的人會(huì)不知道該注釋創(chuàng)建了方法。此外,如果將來您需要在這些方法內(nèi)部執(zhí)行一些操作,注釋也是沒用的。 總之,不要試圖用注釋去做那些常規(guī)代碼可以完成的事情。

枚舉

enum非常像public static final int聲明,后者作為枚舉值已經(jīng)使用了很多年。對(duì)int所做的最大也是最明顯的改進(jìn)是類型安全——您不能錯(cuò)誤地用枚舉的一種類型代替另一種類型,這一點(diǎn)和int不同,所有的int對(duì)編譯器來說都是一樣的。除去極少數(shù)例外的情況,通常都應(yīng)該用enum實(shí)例替換全部的枚舉風(fēng)格的int結(jié)構(gòu)。

枚舉提供了一些附加的特性。EnumMap和EnumSet這兩個(gè)實(shí)用類是專門為枚舉優(yōu)化的標(biāo)準(zhǔn)集合實(shí)現(xiàn)。如果知道集合只包含枚舉類型,那么應(yīng)該使用這些專門的集合來代替HashMap或HashSet。

大部分情況下,可以使用enum對(duì)代碼中的所有public static final int做插入替換。它們是可比的,并且可以靜態(tài)導(dǎo)入,所以對(duì)它們的引用看起來是等同的,即使是對(duì)于內(nèi)部類(或內(nèi)部枚舉類型)。注意,比較枚舉類型的時(shí)候,聲明它們的指令表明了它們的順序值。

“隱藏的”靜態(tài)方法

兩個(gè)靜態(tài)方法出現(xiàn)在所有枚舉類型聲明中。因?yàn)樗鼈兪敲杜e子類上的靜態(tài)方法,而不是Enum本身的方法,所以它們?cè)趈ava.lang.Enum的javadoc中沒有出現(xiàn)。

第一個(gè)是values(),返回一個(gè)枚舉類型所有可能值的數(shù)組。
第二個(gè)是valueOf(),為提供的字符串返回一個(gè)枚舉類型,該枚舉類型必須精確地匹配源代碼聲明。

方法

關(guān)于枚舉類型,我們最喜歡的一個(gè)方面是它可以有方法。過去您可能需要編寫一些代碼,對(duì)public static final int進(jìn)行轉(zhuǎn)換,把它從數(shù)據(jù)庫(kù)類型轉(zhuǎn)換為JDBC URL。而現(xiàn)在則可以讓枚舉類型本身帶一個(gè)整

理代碼的方法。下面就是一個(gè)例子,包括DatabaseType枚舉類型的抽象方法以及每個(gè)枚舉實(shí)例中提供的實(shí)現(xiàn):

public enum DatabaseType {
ORACLE {
public String getJdbcUrl() {...}
},
MYSQL {
public String getJdbcUrl() {...}
};
public abstract String getJdbcUrl();
}

現(xiàn)在枚舉類型可以直接提供它的實(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è)例子,將是兼容的:

復(fù)制代碼 代碼如下:
Log.log(String code, String... args)

所有的可變參數(shù)都是源兼容的——那就是說,如果重新編譯log()方法的所有調(diào)用程序,可以直接替換全部的四個(gè)方法。然而,如果需要向后的二進(jìn)制兼容性,那么就需要舍去前三個(gè)方法。只有最后那個(gè)帶一個(gè)字符串?dāng)?shù)組參數(shù)的方法等效于可變參數(shù)版本,因此可以被可變參數(shù)版本替換。

類型強(qiáng)制轉(zhuǎn)換

如果希望調(diào)用程序了解應(yīng)該使用哪種類型的參數(shù),那么應(yīng)該避免用可變參數(shù)進(jìn)行類型強(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聲明:

復(fù)制代碼 代碼如下:
Log.log(String message, Exception e, Object... objects) {...}

不要使用可變參數(shù)破壞類型系統(tǒng)。需要強(qiáng)類型化時(shí)才可以使用它。對(duì)于這個(gè)規(guī)則,PrintStream.printf()是一個(gè)有趣的例外:它提供類型信息作為自己的第一個(gè)參數(shù),以便稍后可以接受那些類型。

協(xié)變返回

協(xié)變返回的基本用法是用于在已知一個(gè)實(shí)現(xiàn)的返回類型比API更具體的時(shí)候避免進(jìn)行類型強(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è)反模式:

直接字段訪問。為了規(guī)避API限制,一些實(shí)現(xiàn)把子類直接暴露為字段:

復(fù)制代碼 代碼如下:
ZooImpl._animal

另一種形式是,在知道實(shí)現(xiàn)的實(shí)際上是特定的子類的情況下,在調(diào)用程序中執(zhí)行向下轉(zhuǎn)換:
復(fù)制代碼 代碼如下:
((AnimalImpl)ZooImpl.getAnimal()).implMethod();

我看到的最后一種形式是一個(gè)具體的方法,該方法用來避免由一個(gè)完全不同的簽名所引發(fā)的問題:

復(fù)制代碼 代碼如下:
ZooImpl._getAnimal();

這三種模式都有它們的問題和局限性。要么是不夠整潔,要么就是暴露了不必要的實(shí)現(xiàn)細(xì)節(jié)。

協(xié)變

協(xié)變返回模式就比較整潔、安全并且易于維護(hù),它也不需要類型強(qiáng)制轉(zhuǎn)換或特定的方法或字段:

public AnimalImpl getAnimal(){ 
return new AnimalImpl(); 
}

使用結(jié)果:

復(fù)制代碼 代碼如下:
ZooImpl.getAnimal().implMethod();

使用泛型

我們將從兩個(gè)角度來了解泛型:使用泛型和構(gòu)造泛型。我們不討論List、Set和Map的顯而易見的用法。知道泛型集合是強(qiáng)大的并且應(yīng)該經(jīng)常使用就足夠了。

我們將討論泛型方法的使用以及編譯器推斷類型的方法。通常這些都不會(huì)出問題,但是當(dāng)出問題時(shí),錯(cuò)誤信息會(huì)非常令人費(fèi)解,所以需要了解如何修復(fù)這些問題。

泛型方法

除了泛型類型,Java 5還引入了泛型方法。在這個(gè)來自java.util.Collections的例子中,構(gòu)造了一個(gè)單元素列表。新的List的元素類型是根據(jù)傳入方法的對(duì)象的類型來推斷的:

復(fù)制代碼 代碼如下:
static <T> List<T> Collections.singletonList(T o)

示例用法:

public List<Integer> getListOfOne() {
return Collections.singletonList(1);
}

在示例用法中,我們傳入了一個(gè)int。所以方法的返回類型就是List<Integer>。編譯器把T推斷為Integer。這和泛型類型是不同的,因?yàn)槟ǔ2恍枰@式地指定類型參數(shù)。

這也顯示了自動(dòng)裝箱和泛型的相互作用。類型參數(shù)必須是引用類型:這就是為什么我們得到的是List<Integer>而不是List<int>。

不帶參數(shù)的泛型方法

emptyList()方法與泛型一起引入,作為java.util.Collections中EMPTY_LIST字段的類型安全置換:

復(fù)制代碼 代碼如下:
static <T> List<T> Collections.emptyList()

示例用法:

public List<Integer> getNoIntegers() {
return Collections.emptyList();
}

與先前的例子不同,這個(gè)方法沒有參數(shù),那么編譯器如何推斷T的類型呢?基本上,它將嘗試使用一次參數(shù)。如果沒有起作用,它再次嘗試使用返回或賦值類型。在本例中,返回的是List<Integer>,所以T被推斷為Integer。

如果在返回語(yǔ)句或賦值語(yǔ)句之外的位置調(diào)用泛型方法會(huì)怎么樣呢?那么編譯器將無法執(zhí)行類型推斷的第二次傳送。在下面這個(gè)例子中,emptyList()是從條件運(yùn)算符內(nèi)部調(diào)用的:

public List<Integer> getNoIntegers() {
return x ? Collections.emptyList() : null;
}

因?yàn)榫幾g器看不到返回上下文,也不能推斷T,所以它放棄并采用Object。您將看到一個(gè)錯(cuò)誤消息,比如:“無法將List<Object>轉(zhuǎn)換為L(zhǎng)ist<Integer>?!?
為了修復(fù)這個(gè)錯(cuò)誤,應(yīng)顯式地向方法調(diào)用傳遞類型參數(shù)。這樣,編譯器就不會(huì)試圖推斷類型參數(shù),就可以獲得正確的結(jié)果:

復(fù)制代碼 代碼如下:
return x ? Collections.<Integer>emptyList() : null;

這種情況經(jīng)常發(fā)生的另一個(gè)地方是在方法調(diào)用中。如果一個(gè)方法帶一個(gè)List<String>參數(shù),并且需要為那個(gè)參數(shù)調(diào)用這個(gè)傳遞的emptyList(),那么也需要使用這個(gè)語(yǔ)法。

集合之外

這里有三個(gè)泛型類型的例子,它們不是集合,而是以一種新穎的方式使用泛型。這三個(gè)例子都來自標(biāo)準(zhǔn)的Java庫(kù):

復(fù)制代碼 代碼如下:
Class<T>

Class在類的類型上被參數(shù)化了。這就使無需類型強(qiáng)制轉(zhuǎn)換而構(gòu)造一個(gè)newInstance成為可能。
復(fù)制代碼 代碼如下:
Comparable<T>

Comparable被實(shí)際的比較類型參數(shù)化。這就在compareTo()調(diào)用時(shí)提供了更強(qiáng)的類型化。例如,String實(shí)現(xiàn)Comparable<String>。對(duì)除String之外的任何東西調(diào)用compareTo(),都會(huì)在編譯時(shí)失敗。
復(fù)制代碼 代碼如下:
Enum<E extends Enum<E>>

Enum被枚舉類型參數(shù)化。一個(gè)名為Color的枚舉類型將擴(kuò)展Enum<Color>。getDeclaringClass()方法返回枚舉類型的類對(duì)象,在這個(gè)例子中就是一個(gè)Color對(duì)象。它與getClass()不同,后者可能返回一個(gè)無名類。

通配符

泛型最復(fù)雜的部分是對(duì)通配符的理解。我們將討論三種類型的通配符以及它們的用途。

首先讓我們了解一下數(shù)組是如何工作的??梢詮囊粋€(gè)Integer[]為一個(gè)Number[]賦值。如果嘗試把一個(gè)Float寫到Number[]中,那么可以編譯,但在運(yùn)行時(shí)會(huì)失敗,出現(xiàn)一個(gè)ArrayStoreException:

Integer[] ia = new Integer[5];
Number[] na = ia;
na[0] = 0.5; // compiles, but fails at runtime

如果試圖把該例直接轉(zhuǎn)換成泛型,那么會(huì)在編譯時(shí)失敗,因?yàn)橘x值是不被允許的:

List<Integer> iList = new ArrayList<Integer>();
List<Number> nList = iList; // not allowed
nList.add(0.5);

如果使用泛型,只要代碼在編譯時(shí)沒有出現(xiàn)警告,就不會(huì)遇到運(yùn)行時(shí)ClassCastException。

上限通配符

我們想要的是一個(gè)確切元素類型未知的列表,這一點(diǎn)與數(shù)組是不同的。
List<Number>是一個(gè)列表,其元素類型是具體類型Number。
List<? extends Number>是一個(gè)確切元素類型未知的列表。它是Number或其子類型。

上限

如果我們更新初始的例子,并賦值給List<? extends Number>,那么現(xiàn)在賦值就會(huì)成功了:

List<Integer> iList = new ArrayList<Integer>();
List<? extends Number> nList = iList;
Number n = nList.get(0);
nList.add(0.5); // Not allowed

我們可以從列表中得到Number,因?yàn)闊o論列表的確切元素類型是什么(Float、Integer或Number),我們都可以把它賦值給Number。

我們?nèi)匀徊荒馨迅↑c(diǎn)類型插入列表中。這會(huì)在編譯時(shí)失敗,因?yàn)槲覀儾荒茏C明這是安全的。如果我們想要向列表中添加浮點(diǎn)類型,它將破壞iList的初始類型安全——它只存儲(chǔ)Integer。

通配符給了我們比數(shù)組更多的表達(dá)能力。

為什么使用通配符

在下面這個(gè)例子中,通配符用于向API的用戶隱藏類型信息。在內(nèi)部,Set被存儲(chǔ)為CustomerImpl。而API的用戶只知道他們正在獲取一個(gè)Set,從中可以讀取Customer。

此處通配符是必需的,因?yàn)闊o法從Set<CustomerImpl>向Set<Customer>賦值:

public class CustomerFactory {
private Set<CustomerImpl> _customers;
public Set<? extends Customer> getCustomers() {
return _customers;
}
}

通配符和協(xié)變返回

通配符的另一種常見用法是和協(xié)變返回一起使用。與賦值相同的規(guī)則可以應(yīng)用到協(xié)變返回上。如果希望在重寫的方法中返回一個(gè)更具體的泛型類型,聲明的方法必須使用通配符:

public interface NumberGenerator {
public List<? extends Number> generate();
}
public class FibonacciGenerator extends NumberGenerator {
public List<Integer> generate() {
...
}
}

如果要使用數(shù)組,接口可以返回Number[],而實(shí)現(xiàn)可以返回Integer[]。

下限

我們所談的主要是關(guān)于上限通配符的。還有一個(gè)下限通配符。List<? super Number>是一個(gè)確切“元素類型”未知的列表,但是可能是Mnumber,或者Number的超類型。所以它可能是一個(gè)List<Number>或一個(gè)List<Object>。

下限通配符遠(yuǎn)沒有上限通配符那樣常見,但是當(dāng)需要它們的時(shí)候,它們就是必需的。

下限與上限

List<? extends Number> readList = new ArrayList<Integer>();
Number n = readList.get(0);
List<? super Number> writeList = new ArrayList<Object>();
writeList.add(new Integer(5));

第一個(gè)是可以從中讀數(shù)的列表。

第二個(gè)是可以向其寫數(shù)的列表。

無界通配符

最后,List<?>列表的內(nèi)容可以是任何類型,而且它與List<? extends Object>幾乎相同。可以隨時(shí)讀取Object,但是不能向列表中寫入內(nèi)容。

公共API中的通配符

總之,正如前面所說,通配符在向調(diào)用程序隱藏實(shí)現(xiàn)細(xì)節(jié)方面是非常重要的,但即使下限通配符看起來是提供只讀訪問,由于remove(int position)之類的非泛型方法,它們也并非如此。如果您想要一個(gè)真正不變的集合,可以使用java.util.Collection上的方法,比如unmodifiableList()。

編寫API的時(shí)候要記得通配符。通常,在傳遞泛型類型時(shí),應(yīng)該嘗試使用通配符。它使更多的調(diào)用程序可以訪問API。

通過接收List<? extends Number>而不是List<Number>,下面的方法可以由許多不同類型的列表調(diào)用:

復(fù)制代碼 代碼如下:
void removeNegatives(List<? extends Number> list);

構(gòu)造泛型類型

現(xiàn)在我們將討論構(gòu)造自己的泛型類型。我們將展示一些例子,其中通過使用泛型可以提高類型安全性,我們還將討論一些實(shí)現(xiàn)泛型類型時(shí)的常見問題。

集合風(fēng)格(Collection-like)的函數(shù)

第一個(gè)泛型類的例子是一個(gè)集合風(fēng)格的例子。Pair有兩個(gè)類型參數(shù),而且字段是類型的實(shí)例:

public final class Pair<A,B> {
public final A first;
public final B second;
public Pair(A first, B second) {
this.first = first;
this.second = second;
}
}

這使從方法返回兩個(gè)項(xiàng)而無需為每個(gè)兩種類型的組合編寫專用的類成為可能。另一種方法是返回Object[],而這樣是類型不安全或者不整潔的。

在下面的用法中,我們從方法返回一個(gè)File和一個(gè)Boolean。方法的客戶端可以直接使用字段而無需類型強(qiáng)制轉(zhuǎn)換:

public Pair<File,Boolean> getFileAndWriteStatus(String path){
// create file and status
return new Pair<File,Boolean>(file, status);
}
Pair<File,Boolean> result = getFileAndWriteStatus("...");
File f = result.first;
boolean writeable = result.second;

集合之外

在下面這個(gè)例子中,泛型被用于附加的編譯時(shí)安全性。通過把DBFactory類參數(shù)化為所創(chuàng)建的Peer類型,您實(shí)際上是在強(qiáng)制Factory子類返回一個(gè)Peer的特定子類型:

public abstract class DBFactory<T extends DBPeer> {
protected abstract T createEmptyPeer();
public List<T> get(String constraint) {
List<T> peers = new ArrayList<T>();
// database magic
return peers;
}
}

通過實(shí)現(xiàn)DBFactory<Customer>,CustomerFactory必須從createEmptyPeer()返回一個(gè)Customer:

public class CustomerFactory extends DBFactory<Customer>{
public Customer createEmptyPeer() {
return new Customer();
}
}

泛型方法

不管想要對(duì)參數(shù)之間還是參數(shù)與返回類型之間的泛型類型施加約束,都可以使用泛型方法:

例如,如果編寫的反轉(zhuǎn)函數(shù)是在位置上反轉(zhuǎn),那么可能不需要泛型方法。然而,如果希望反轉(zhuǎn)返回一個(gè)新的List,那么可能會(huì)希望新List的元素類型與傳入的List的類型相同。在這種情況下,就需要一個(gè)泛型方法:

復(fù)制代碼 代碼如下:
<T> List<T> reverse(List<T> list)

具體化

當(dāng)實(shí)現(xiàn)一個(gè)泛型類時(shí),您可能想要構(gòu)造一個(gè)數(shù)組T[]。因?yàn)榉盒褪峭ㄟ^擦除(erasure)實(shí)現(xiàn)的,所以這是不允許的。

您可以嘗試把Object[]強(qiáng)制轉(zhuǎn)換為T[]。但這是不安全的。

具體化解決方案

按照泛型教程的慣例,解決方案使用的是“類型令牌”,通過向構(gòu)造函數(shù)添加一個(gè)Class<T>參數(shù),可以強(qiáng)制客戶端為類的類型參數(shù)提供正確的類對(duì)象:

public class ArrayExample<T> {
private Class<T> clazz;
public ArrayExample(Class<T> clazz) {
this.clazz = clazz;
}
public T[] getArray(int size) {
return (T[])Array.newInstance(clazz, size);
}
}

為了構(gòu)造ArrayExample<String>,客戶端必須把String.class傳遞給構(gòu)造函數(shù),因?yàn)镾tring.class的類型是Class<String>。

擁有類對(duì)象使構(gòu)造一個(gè)具有正確元素類型的數(shù)組成為可能

希望本文所述對(duì)大家Java程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • intellij idea設(shè)置統(tǒng)一JavaDoc模板的方法詳解

    intellij idea設(shè)置統(tǒng)一JavaDoc模板的方法詳解

    這篇文章主要介紹了intellij idea設(shè)置統(tǒng)一JavaDoc模板的方法詳解,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • IISExpress?配置允許外部訪問詳細(xì)介紹

    IISExpress?配置允許外部訪問詳細(xì)介紹

    這篇文章主要介紹了?IISExpress?配置允許外部訪問詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下
    2016-11-11
  • Hibernate中Session增刪改查操作代碼詳解

    Hibernate中Session增刪改查操作代碼詳解

    這篇文章主要介紹了Hibernate中Session增刪改查操作代碼詳解,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • 記一次線程爆滿導(dǎo)致服務(wù)器崩潰的問題排查及解決

    記一次線程爆滿導(dǎo)致服務(wù)器崩潰的問題排查及解決

    這篇文章主要介紹了記一次線程爆滿導(dǎo)致服務(wù)器崩潰的問題排查及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • Java消息隊(duì)列Kafka的簡(jiǎn)單概述

    Java消息隊(duì)列Kafka的簡(jiǎn)單概述

    這篇文章主要介紹了Java消息隊(duì)列Kafka的簡(jiǎn)單概述,消息系統(tǒng)負(fù)責(zé)將數(shù)據(jù)從一個(gè)應(yīng)用程序傳輸?shù)搅硪粋€(gè)應(yīng)用程序,應(yīng)用程序可以專注于數(shù)據(jù),不擔(dān)心如何共享它,需要的朋友可以參考下
    2023-07-07
  • java中變量和常量詳解

    java中變量和常量詳解

    這篇文章主要介紹了Java中變量和常量詳解,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • springboot亂碼問題解決方案

    springboot亂碼問題解決方案

    這篇文章主要介紹了springboot亂碼問題解決方案,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • Mybatis Plus 代碼生成器的實(shí)現(xiàn)

    Mybatis Plus 代碼生成器的實(shí)現(xiàn)

    這篇文章主要介紹了Mybatis Plus 代碼生成器的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • PL/SQL實(shí)現(xiàn)JAVA中的split()方法的例子

    PL/SQL實(shí)現(xiàn)JAVA中的split()方法的例子

    這篇文章主要介紹了PL/SQL實(shí)現(xiàn)JAVA中的split()方法的例子的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-07-07
  • SpringBoot使用Feign調(diào)用其他服務(wù)接口

    SpringBoot使用Feign調(diào)用其他服務(wù)接口

    這篇文章主要介紹了SpringBoot使用Feign調(diào)用其他服務(wù)接口,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03

最新評(píng)論