2013年12月21日 星期六

Type Inference for Generic Instance Creation
許裕永 譯 (原文內容取自 Oracle 官網)

譯者註: Generic Class 一般翻譯為 泛型類別, 本文翻譯為 限型類別(可以限定單一型別的類別)

Type Inference for Generic Instance Creation - You can replace the type arguments required to invoke the constructor of a generic class with an empty set of type parameters (<>) as long as the compiler can infer the type arguments from the context. This pair of angle brackets is informally called the diamond.
建立限型類別的實體時的型別推斷 - 你可以用空的(<>) 符號, 取代呼限型類別的建構方法時, 必需指定限型類別的型別參數的設定, 只要編譯器可以從內容中推斷出參數的型別.

This pair of angle brackets is informally called the diamond.
這對尖括號非正式的稱呼為鑽石.

For example, consider the following variable declaration:
在範例中, 了解下列變數的宣告:

Map<String, List<String>> myMap = new HashMap<String, List<String>>();
In Java SE 7, you can substitute the parameterized type of the constructor with an empty set of type parameters (<>):
在 Java SE7 中, 你可以用設定為空的參數型別(<>)取代建構方法中的參數型別:

Map<String, List<String>> myMap = new HashMap<>();
Note that to take advantage of automatic type inference during generic class instantiation, you must specify the diamond. In the following example, the compiler generates an unchecked conversion warning because theHashMap() constructor refers to the HashMap raw type, not the Map<String, List<String>> type:
注意要取得限型類別實體化時能自動判斷參數型別的優點, 你必須宣告鑽石符號. 下列範例, 編譯器將產生 unchecked conversion warning 因為 HashMap() 建構時有提供宣告變數時的 限型型別, 但未提供建構方法的限型型別.

Map<String, List<String>> myMap = new HashMap(); // unchecked conversion warning
Java SE 7 supports limited type inference for generic instance creation; you can only use type inference if the parameterized type of the constructor is obvious from the context. For example, the following example does not compile:
Java SE 7 支援有限度的型別推斷在 限型類別的實體建構時, 你只可以在建構方法要設定的限型型別的參數, 可以很顯然的從上下文中推斷出來時, 使用型別推斷. 如同範例, 下列範例無法編譯:

List<String> list = new ArrayList<>();
list.add("A");

// The following statement should fail since addAll expects
//下列敍述將失敗因為 addAll 的期待

// Collection<? extends String>
list.addAll(new ArrayList<>());

Note that the diamond often works in method calls; however, it is suggested that you use the diamond primarily for variable declarations.
注意鑽石符號時常在方法呼叫時使用; 然而建議你鑽石符號主要是使用在變數宣告時.

In comparison, the following example compiles:
對照之下, 下列範例可以編譯:

// The following statements compile:
//下列敍述可以編譯

List<? extends String> list2 = new ArrayList<>();
list.addAll(list2);

Type Inference and Generic Constructors of Generic and Non-Generic Classes
限型類別與非限型類別的限型建構方法的型別推斷

Note that constructors can be generic (in other words, declare their own formal type parameters) in both generic and non-generic classes. Consider the following example:
注意無論是限型類別或非限型類別的建構方法, 都可以宣告為限型的 (換句話說, 宣告它們自己的特定型別參數). 了解下列範例:

class MyClass<X> {
 <T> MyClass(T t) {
  // ...
 }
}
Consider the following instantiation of the class MyClass, which is valid in Java SE 7 and prior releases:
了解下列 MyClass 的實體過程, 它在 Java SE7 是合法而且優先發表的:

new MyClass<Integer>("");
This statement creates an instance of the parameterized type MyClass<Integer>; the statement explicitly specifies the type Integer for the formal type parameter, X, of the generic class MyClass<X>.
這個敍述建立了一個 MyClass<Integer> 型別的實體; 此敍述明確的宣告 Integer 型別為限型類別 MyClass<X> 的限型型別, X.

Note that the constructor for this generic class contains a formal type parameter, T. The compiler infers the type String for the formal type parameter, T, of the constructor of this generic class (because the actual parameter of this constructor is a Stringobject).
注意此限型類別的建構方法包含了一個特定型別參數, T. 編譯器把 String 型別推斷為這個限型類別的建構方法的特定型別, T
(因為這個建構方法的參數實際上就是一個 String 型別的物件).


Compilers from releases prior to Java SE 7 are able to infer the actual type parameters of generic constructors, similar to generic methods. However, the compiler in Java SE 7 can infer the actual type parameters of the generic class being instantiated if you use the diamond (<>). Consider the following examples, which are valid for Java SE 7 and later:
從Java SE 7之前版本的編譯器就能夠推斷出限型類別的建構方法的實際參數型別,類似 限型類別中的方法。但是,如果你使用的鑽石符號(<>), Java SE7編譯器可以在 限型類別被實例化時, 推斷出實際的參數的型別.

MyClass<Integer> myObject = new MyClass<>("");
In this example, the compiler infers the type Integer for the formal type parameter, X, of the generic class MyClass<X>. It infers the type String for the formal type parameter, T, of the constructor of this generic class.
在這個範例中, 編譯器推斷型別 Integer 為限型類別 MyClass<X> 的 參數 X 的正式型別. 它也推斷型別 String 為這個限型類別的建構方法的參數 T 的正式型別.

MyClass<Integer> myObject = new <String> MyClass<>("");
In this example, the compiler infers the type Integer for the formal type parameter, X, of the generic class MyClass<X>. The statement explicitly specifies the type String for the formal type parameter, T, of the constructor of this generic class.
在這個範例中, 編譯器推斷型別 Integer 為限型類別 MyClass<X> 的 參數 X 的正式型別. 但敍述中明確宣告型別 String 為這個限型類別的建構方法的參數 T 的正式型別.
 

沒有留言:

張貼留言