欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
體驗JAVA 5的新增語(yǔ)言特性

  Java 5.0發(fā)布了,許多人都將開(kāi)始使用這個(gè)JDK版本的一些新增特性。從增強的for循環(huán)到諸如泛型(generic)之類(lèi)更復雜的特性,都將很快出現在您所編寫(xiě)的代碼中。我們剛剛完成了一個(gè)基于Java 5.0的大型任務(wù),而本文就是要介紹我們使用這些新特性的體驗。本文不是一篇入門(mén)性的文章,而是對這些特性以及它們所產(chǎn)生的影響的深入介紹,同時(shí)還給出了一些在項目中更有效地使用這些特性的技巧。

簡(jiǎn)介
  在JDK 1.5的beta階段,我們?yōu)锽EA的Java IDE開(kāi)發(fā)了一個(gè)Java 5編譯器。因為我們實(shí)現了許多新特性,所以人們開(kāi)始以新的方式利用它們;有些用法很聰明,而有些用法明顯應該被列入禁用清單。編譯器本身使用了新的語(yǔ)言特性,所以我們也獲得了使用這些特性維護代碼的直接體驗。本文將介紹其中的許多特性和使用它們的體驗。
  我們假定您已經(jīng)熟悉了這些新特性,所以不再全面介紹每個(gè)特性,而是談?wù)撘恍┯腥さ?、但很可能不太明顯的內容和用法。這些技巧出自我們的實(shí)際體驗,并大致按照語(yǔ)言特性進(jìn)行了分類(lèi)。
  我們將從最簡(jiǎn)單的特性開(kāi)始,逐步過(guò)渡到高級特性。泛型所包含的內容特別豐富,因此占了本文一半的篇幅。

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

Init表達式
  在循環(huán)中,初始化表達式只計算一次。這意味著(zhù)您通??梢砸瞥粋€(gè)變量聲明。在這個(gè)例子中,我們必須創(chuàng )建一個(gè)整型數組來(lái)保存computeNumbers()的結果,以防止每一次循環(huán)都重新計算該方法。您可以看到,下面的代碼要比上面的代碼整潔一些,并且沒(méi)有泄露變量numbers:
未增強的For:int sum = 0;Integer[] numbers = computeNumbers();for (int i=0; i < numbers.length ; i++)sum += numbers[i];增強后的For:int sum = 0;for ( int number: computeNumbers() )sum += number;
局限性
有時(shí)需要在迭代期間訪(fǎng)問(wèn)迭代器或下標,看起來(lái)增強的for循環(huán)應該允許該操作,但事實(shí)上不是這樣,請看下面的例子:
for (int i=0; i < numbers.length ; i++) {if (i != 0) System.out.print(",");System.out.print(numbers[i]);}

  我們希望將數組中的值打印為一個(gè)用逗號分隔的清單。我們需要知道目前是否是第一項,以便確定是否應該打印逗號。使用增強的for循環(huán)是無(wú)法獲知這種信息的。我們需要自己保留一個(gè)下標或一個(gè)布爾值來(lái)指示是否經(jīng)過(guò)了第一項。   這是另一個(gè)例子:

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

  在此例中,我們想從整數集合中刪除負數項。為此,需要對迭代器調用一個(gè)方法,但是當使用增強的for 循環(huán)時(shí),迭代器對我們來(lái)說(shuō)是看不到的。因此,我們只能使用Java 5之前版本的迭代方法。   順便說(shuō)一下,這里需要注意的是,由于Iterator是泛型,所以其聲明是Iterator<Integer>。許多人都忘記了這一點(diǎn)而使用了Iterator的原始格式。

注釋
  注釋處理是一個(gè)很大的話(huà)題。因為本文只關(guān)注核心的語(yǔ)言特性,所以我們不打算涵蓋它所有的可能形式和陷阱?! ∥覀儗⒂懻搩戎玫淖⑨?zhuān)⊿uppressWarnings,Deprecated和Override)以及一般注釋處理的局限性。

Suppress Warnings
  該注釋關(guān)閉了類(lèi)或方法級別的編譯器警告。有時(shí)候您比編譯器更清楚地知道,代碼必須使用一個(gè)被否決的方法或執行一些無(wú)法靜態(tài)確定是否類(lèi)型安全的動(dòng)作,而使用:

@SuppressWarnings("deprecation")public static void selfDestruct() {Thread.currentThread().stop();}

  這可能是內置注釋最有用的地方。遺憾的是,1.5.0_04的javac不支持它。但是1.6支持它,并且Sun正在努力將其向后移植到1.5中。
Eclipse 3.1中支持該注釋?zhuān)渌鸌DE也可能支持它。這允許您把代碼徹底地從警告中解脫出來(lái)。如果在編譯時(shí)出現警告,可以確定是您剛剛把它添加進(jìn)來(lái)——以幫助查看那些可能不安全的代碼。隨著(zhù)泛型的添加,它使用起來(lái)將更趁手。

Deprecated
  遺憾的是,Deprecated沒(méi)那么有用。它本來(lái)旨在替換@deprecated javadoc標簽,但是由于它不包含任何字段,所以也就沒(méi)有方法來(lái)建議deprecated類(lèi)或方法的用戶(hù)應該使用什么做為替代品。大多數用法都同時(shí)需要javadoc標簽和這個(gè)注釋。

Override
  Override表示,它所注釋的方法應該重寫(xiě)超類(lèi)中具有相同簽名的方法:

@Overridepublic int hashCode() {...}

  看上面的例子,如果沒(méi)有在hashCode中將“C”大寫(xiě),在編譯時(shí)不會(huì )出現錯誤,但是在運行時(shí)將無(wú)法像期望的那樣調用該方法。通過(guò)添加Override標簽,編譯器會(huì )提示它是否真正地執行了重寫(xiě)。
  在超類(lèi)發(fā)生改變的情況中,這也很有幫助。如果向該方法中添加一個(gè)新參數,而且方法本身也被重命名了,那么子類(lèi)將突然不能編譯,因為它不再重寫(xiě)超類(lèi)的任何東西。

其它注釋
  注釋在其他場(chǎng)景中非常有用。當不是直接修改行為而是增強行為時(shí),特別是在添加樣板代碼的情況下,注釋在諸如EJB和Web services這樣的框架中運行得非常好。
注釋不能用做預處理器。Sun的設計特別預防了完全因為注釋而修改類(lèi)的字節碼。這樣可以正確地理解該語(yǔ)言的成果,而且IDE之類(lèi)的工具也可以執行深入的代碼分析和重構之類(lèi)的功能。
注釋不是銀彈。第一次遇到的時(shí)候,人們試圖嘗試各種技巧。請看下面這個(gè)從別人那里獲得的建議:

public class Foo { @Propertyprivate int bar; }

  其思想是為私有字段bar自動(dòng)創(chuàng )建getter和setter方法。遺憾的是,這個(gè)想法有兩個(gè)失敗之處:1)它不能運行,2)它使代碼難以閱讀和處理。   它是無(wú)法實(shí)現的,因為前面已經(jīng)提到了,Sun特別阻止了對出現注釋的類(lèi)進(jìn)行修改。
  即使是可能的,它也不是一個(gè)好主意,因為它使代碼可讀性差。第一次看到這段代碼的人會(huì )不知道該注釋創(chuàng )建了方法。此外,如果將來(lái)您需要在這些方法內部執行一些操作,注釋也是沒(méi)用的。   總之,不要試圖用注釋去做那些常規代碼可以完成的事情。

枚舉
  enum非常像public static final int聲明,后者作為枚舉值已經(jīng)使用了很多年。對int所做的最大也是最明顯的改進(jìn)是類(lèi)型安全——您不能錯誤地用枚舉的一種類(lèi)型代替另一種類(lèi)型,這一點(diǎn)和int不同,所有的int對編譯器來(lái)說(shuō)都是一樣的。除去極少數例外的情況,通常都應該用enum實(shí)例替換全部的枚舉風(fēng)格的int結構。
  枚舉提供了一些附加的特性。EnumMap和EnumSet這兩個(gè)實(shí)用類(lèi)是專(zhuān)門(mén)為枚舉優(yōu)化的標準集合實(shí)現。如果知道集合只包含枚舉類(lèi)型,那么應該使用這些專(zhuān)門(mén)的集合來(lái)代替HashMap或HashSet。
  大部分情況下,可以使用enum對代碼中的所有public static final int做插入替換。它們是可比的,并且可以靜態(tài)導入,所以對它們的引用看起來(lái)是等同的,即使是對于內部類(lèi)(或內部枚舉類(lèi)型)。注意,比較枚舉類(lèi)型的時(shí)候,聲明它們的指令表明了它們的順序值。

“隱藏的”靜態(tài)方法
  兩個(gè)靜態(tài)方法出現在所有枚舉類(lèi)型聲明中。因為它們是枚舉子類(lèi)上的靜態(tài)方法,而不是Enum本身的方法,所以它們在java.lang.Enum的javadoc中沒(méi)有出現。
  第一個(gè)是values(),返回一個(gè)枚舉類(lèi)型所有可能值的數組。
  第二個(gè)是valueOf(),為提供的字符串返回一個(gè)枚舉類(lèi)型,該枚舉類(lèi)型必須精確地匹配源代碼聲明。
方法
  關(guān)于枚舉類(lèi)型,我們最喜歡的一個(gè)方面是它可以有方法。過(guò)去您可能需要編寫(xiě)一些代碼,對public static final int進(jìn)行轉換,把它從數據庫類(lèi)型轉換為JDBC URL。而現在則可以讓枚舉類(lèi)型本身帶一個(gè)整理代碼的方法。下面就是一個(gè)例子,包括DatabaseType枚舉類(lèi)型的抽象方法以及每個(gè)枚舉實(shí)例中提供的實(shí)現:

  public enum  DatabaseType {ORACLE {public String getJdbcUrl() {...}},MYSQL {public String getJdbcUrl() {...}};public abstract String getJdbcUrl();}
  現在枚舉類(lèi)型可以直接提供它的實(shí)用方法。例如:

DatabaseType dbType = ...;
String jdbcURL = dbType.getJdbcUrl();

  要獲取URL,必須預先知道該實(shí)用方法在哪里。


可變參數(Vararg)
  正確地使用可變參數確實(shí)可以清理一些垃圾代碼。典型的例子是一個(gè)帶有可變的String參數個(gè)數的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)
  當討論可變參數時(shí),比較有趣的是,如果用新的可變參數替換前四個(gè)例子,將是兼容的:
Log.log(String code, String... args)
  所有的可變參數都是源兼容的——那就是說(shuō),如果重新編譯log()方法的所有調用程序,可以直接替換全部的四個(gè)方法。然而,如果需要向后的二進(jìn)制兼容性,那么就需要舍去前三個(gè)方法。只有最后那個(gè)帶一個(gè)字符串數組參數的方法等效于可變參數版本,因此可以被可變參數版本替換。

類(lèi)型強制轉換

  如果希望調用程序了解應該使用哪種類(lèi)型的參數,那么應該避免用可變參數進(jìn)行類(lèi)型強制轉換??聪旅孢@個(gè)例子,第一項希望是String,第二項希望是Exception:
    Log.log(Object...  objects) {String message = (String)objects[0];if (objects.length > 1) {Exception e = (Exception)objects[1];// Do something with the exception}}
  方法簽名應該如下所示,相應的可變參數分別使用String和Exception聲明:

Log.log(String message, Exception e, Object... objects) {...}

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

協(xié)變返回

  協(xié)變返回的基本用法是用于在已知一個(gè)實(shí)現的返回類(lèi)型比API更具體的時(shí)候避免進(jìn)行類(lèi)型強制轉換。在下面這個(gè)例子中,有一個(gè)返回Animal對象的Zoo接口。我們的實(shí)現返回一個(gè)AnimalImpl對象,但是在JDK 1.5之前,要返回一個(gè)Animal對象就必須聲明。:
    public interface Zoo  {public Animal getAnimal();}public class ZooImpl  implements Zoo {public Animal getAnimal(){return new AnimalImpl();}}
  協(xié)變返回的使用替換了三個(gè)反模式:

 

  • 直接字段訪(fǎng)問(wèn)。為了規避API限制,一些實(shí)現把子類(lèi)直接暴露為字段:

ZooImpl._animal

  • 另一種形式是,在知道實(shí)現的實(shí)際上是特定的子類(lèi)的情況下,在調用程序中執行向下轉換:

((AnimalImpl)ZooImpl.getAnimal()).implMethod();

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

ZooImpl._getAnimal();

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

協(xié)變

  協(xié)變返回模式就比較整潔、安全并且易于維護,它也不需要類(lèi)型強制轉換或特定的方法或字段:
public AnimalImpl getAnimal(){
return new AnimalImpl();
}
  使用結果:
ZooImpl.getAnimal().implMethod();

使用泛型
  
我們將從兩個(gè)角度來(lái)了解泛型:使用泛型和構造泛型。我們不討論List、Set和Map的顯而易見(jiàn)的用法。知道泛型集合是強大的并且應該經(jīng)常使用就足夠了。
  我們將討論泛型方法的使用以及編譯器推斷類(lèi)型的方法。通常這些都不會(huì )出問(wèn)題,但是當出問(wèn)題時(shí),錯誤信息會(huì )非常令人費解,所以需要了解如何修復這些問(wèn)題。

泛型方法
  
除了泛型類(lèi)型,Java 5還引入了泛型方法。在這個(gè)來(lái)自java.util.Collections的例子中,構造了一個(gè)單元素列表。新的List的元素類(lèi)型是根據傳入方法的對象的類(lèi)型來(lái)推斷的:
static <T> List<T> Collections.singletonList(T o)示例用法:public List<Integer> getListOfOne() {return Collections.singletonList(1);}

  在示例用法中,我們傳入了一個(gè)int。所以方法的返回類(lèi)型就是List<Integer>。編譯器把T推斷為Integer。這和泛型類(lèi)型是不同的,因為您通常不需要顯式地指定類(lèi)型參數。
這也顯示了自動(dòng)裝箱和泛型的相互作用。類(lèi)型參數必須是引用類(lèi)型:這就是為什么我們得到的是List<Integer>而不是List<int>。

不帶參數的泛型方法
  
emptyList()方法與泛型一起引入,作為java.util.Collections中EMPTY_LIST字段的類(lèi)型安全置換:
static <T> List<T> Collections.emptyList()示例用法:public List<Integer> getNoIntegers() {return Collections.emptyList();}

  與先前的例子不同,這個(gè)方法沒(méi)有參數,那么編譯器如何推斷T的類(lèi)型呢?基本上,它將嘗試使用一次參數。如果沒(méi)有起作用,它再次嘗試使用返回或賦值類(lèi)型。在本例中,返回的是List<Integer>,所以T被推斷為Integer。
  如果在返回語(yǔ)句或賦值語(yǔ)句之外的位置調用泛型方法會(huì )怎么樣呢?那么編譯器將無(wú)法執行類(lèi)型推斷的第二次傳送。在下面這個(gè)例子中,emptyList()是從條件運算符內部調用的:

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

  因為編譯器看不到返回上下文,也不能推斷T,所以它放棄并采用Object。您將看到一個(gè)錯誤消息,比如:“無(wú)法將List<Object>轉換為L(cháng)ist<Integer>?!?
為了修復這個(gè)錯誤,應顯式地向方法調用傳遞類(lèi)型參數。這樣,編譯器就不會(huì )試圖推斷類(lèi)型參數,就可以獲得正確的結果:

return x ? Collections.<Integer>emptyList() : null;

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

集合之外
  這里有三個(gè)泛型類(lèi)型的例子,它們不是集合,而是以一種新穎的方式使用泛型。這三個(gè)例子都來(lái)自標準的Java庫:
  • Class<T>
    Class在類(lèi)的類(lèi)型上被參數化了。這就使無(wú)需類(lèi)型強制轉換而構造一個(gè)newInstance成為可能。
  • Comparable<T>
    Comparable被實(shí)際的比較類(lèi)型參數化。這就在compareTo()調用時(shí)提供了更強的類(lèi)型化。例如,String實(shí)現Comparable<String>。對除String之外的任何東西調用compareTo(),都會(huì )在編譯時(shí)失敗。
  • Enum<E extends Enum<E>>
    Enum被枚舉類(lèi)型參數化。一個(gè)名為Color的枚舉類(lèi)型將擴展Enum<Color>。getDeclaringClass()方法返回枚舉類(lèi)型的類(lèi)對象,在這個(gè)例子中就是一個(gè)Color對象。它與getClass()不同,后者可能返回一個(gè)無(wú)名類(lèi)。
通配符
  
泛型最復雜的部分是對通配符的理解。我們將討論三種類(lèi)型的通配符以及它們的用途。
  首先讓我們了解一下數組是如何工作的??梢詮囊粋€(gè)Integer[]為一個(gè)Number[]賦值。如果嘗試把一個(gè)Float寫(xiě)到Number[]中,那么可以編譯,但在運行時(shí)會(huì )失敗,出現一個(gè)ArrayStoreException:
Integer[] ia = new Integer[5];Number[] na = ia;na[0] = 0.5; // compiles, but fails at runtime如果試圖把該例直接轉換成泛型,那么會(huì )在編譯時(shí)失敗,因為賦值是不被允許的:List<Integer> iList = new ArrayList<Integer>();List<Number> nList = iList; // not allowednList.add(0.5);

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

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

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

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

  我們可以從列表中得到Number,因為無(wú)論列表的確切元素類(lèi)型是什么(Float、Integer或Number),我們都可以把它賦值給Number。
  我們仍然不能把浮點(diǎn)類(lèi)型插入列表中。這會(huì )在編譯時(shí)失敗,因為我們不能證明這是安全的。如果我們想要向列表中添加浮點(diǎn)類(lèi)型,它將破壞iList的初始類(lèi)型安全——它只存儲Integer。
  通配符給了我們比數組更多的表達能力。

為什么使用通配符
  在下面這個(gè)例子中,通配符用于向API的用戶(hù)隱藏類(lèi)型信息。在內部,Set被存儲為CustomerImpl。而API的用戶(hù)只知道他們正在獲取一個(gè)Set,從中可以讀取Customer。
此處通配符是必需的,因為無(wú)法從Set<CustomerImpl>向Set<Customer>賦值:
public class CustomerFactory {private Set<CustomerImpl> _customers;public Set<? extends Customer> getCustomers() {return _customers;}}

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

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

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

下限
  我們所談的主要是關(guān)于上限通配符的。還有一個(gè)下限通配符。List<? super Number>是一個(gè)確切“元素類(lèi)型”未知的列表,但是可能是Mnumber,或者Number的超類(lèi)型。所以它可能是一個(gè)List<Number>或一個(gè)List<Object>。
  下限通配符遠沒(méi)有上限通配符那樣常見(jiàn),但是當需要它們的時(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è)是可以從中讀數的列表。
  第二個(gè)是可以向其寫(xiě)數的列表。

無(wú)界通配符
  最后,List<?>列表的內容可以是任何類(lèi)型,而且它與List<? extends Object>幾乎相同??梢噪S時(shí)讀取Object,但是不能向列表中寫(xiě)入內容。

公共API中的通配符
  總之,正如前面所說(shuō),通配符在向調用程序隱藏實(shí)現細節方面是非常重要的,但即使下限通配符看起來(lái)是提供只讀訪(fǎng)問(wèn),由于remove(int position)之類(lèi)的非泛型方法,它們也并非如此。如果您想要一個(gè)真正不變的集合,可以使用java.util.Collection上的方法,比如unmodifiableList()。
  編寫(xiě)API的時(shí)候要記得通配符。通常,在傳遞泛型類(lèi)型時(shí),應該嘗試使用通配符。它使更多的調用程序可以訪(fǎng)問(wèn)API。
  通過(guò)接收List<? extends Number>而不是List<Number>,下面的方法可以由許多不同類(lèi)型的列表調用:

void removeNegatives(List<? extends Number> list);

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

集合風(fēng)格(Collection-like)的函數
  第一個(gè)泛型類(lèi)的例子是一個(gè)集合風(fēng)格的例子。Pair有兩個(gè)類(lèi)型參數,而且字段是類(lèi)型的實(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è)項而無(wú)需為每個(gè)兩種類(lèi)型的組合編寫(xiě)專(zhuān)用的類(lèi)成為可能。另一種方法是返回Object[],而這樣是類(lèi)型不安全或者不整潔的。
在下面的用法中,我們從方法返回一個(gè)File和一個(gè)Boolean。方法的客戶(hù)端可以直接使用字段而無(wú)需類(lèi)型強制轉換:

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

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

public abstract class DBFactory<T extends DBPeer> {protected abstract T createEmptyPeer();public List<T> get(String constraint) {List<T> peers = new ArrayList<T>();// database magicreturn peers;}}通過(guò)實(shí)現DBFactory<Customer>,CustomerFactory必須從createEmptyPeer()返回一個(gè)Customer:public class CustomerFactory extends DBFactory<Customer>{public Customer createEmptyPeer() {return new Customer();}}

泛型方法
  不管想要對參數之間還是參數與返回類(lèi)型之間的泛型類(lèi)型施加約束,都可以使用泛型方法:
  例如,如果編寫(xiě)的反轉函數是在位置上反轉,那么可能不需要泛型方法。然而,如果希望反轉返回一個(gè)新的List,那么可能會(huì )希望新List的元素類(lèi)型與傳入的List的類(lèi)型相同。在這種情況下,就需要一個(gè)泛型方法:


<T> List<T> reverse(List<T> list)

具體化
  當實(shí)現一個(gè)泛型類(lèi)時(shí),您可能想要構造一個(gè)數組T[]。因為泛型是通過(guò)擦除(erasure)實(shí)現的,所以這是不允許的。
  您可以嘗試把Object[]強制轉換為T(mén)[]。但這是不安全的。

具體化解決方案
  
按照泛型教程的慣例,解決方案使用的是“類(lèi)型令牌”,通過(guò)向構造函數添加一個(gè)Class<T>參數,可以強制客戶(hù)端為類(lèi)的類(lèi)型參數提供正確的類(lèi)對象:
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);}}

  為了構造ArrayExample<String>,客戶(hù)端必須把String.class傳遞給構造函數,因為String.class的類(lèi)型是Class<String>。
擁有類(lèi)對象使構造一個(gè)具有正確元素類(lèi)型的數組成為可能。

結束語(yǔ)
  總而言之,新的語(yǔ)言特性有助于從根本上改變Java。通過(guò)了解在什么場(chǎng)景下使用以及如何使用這些新特性,您將會(huì )編寫(xiě)出更好的代碼。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
J2SE 5.0中的泛型
Java泛型編程最全總結
淺談Java泛型編程
Java中的泛型 第二部分
Java Puzzlers(6)類(lèi)庫之迷
Java泛型編程指南
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久