1,dynamic cast
類似C++的dynamic_cast<T*>操作符,C#的as操作符,Java 5.0提供了安全的dynamic cast功能,不同的是它以類庫的形式提供的,並且類型不符時是要拋異常的,大大降低了可用性:
Class.cast
public T cast(Object obj)
-
Casts an object to the class or interface represented by this Class object.
-
-
Parameters:
-
obj - the object to be cast
-
Returns:
-
the object after casting, or null if obj is null
-
Throws:
-
ClassCastException - if the object is not null and is not assignable to the type T.
-
Since:
-
1.5
2,傳回值協變
interface SomeInterface{
Object get();
}
class CovariantImpl implements SomeInterface{
public String get(){
return "covariant";
}
}
public class TestUntitled2 extends TestCase {
public void testCovariant() {
SomeInterface obj = new CovariantImpl();
Assert.assertEquals("covariant", obj.get());
}
}
3,型別安全的代理
類似唯讀代理Collections.unmodifiableXXX(), 同步代理Collections.synchronizedXXX(), J2SE 5.0提供了型別安全的代理:Collections.checkedXXX()
4,Arrays.deepEquals()
不愧是放在java.util包裡的
5,皇帝的“generic”新衣
加了一堆眼花繚亂的概念,卻受“擦除法”實現方式所累,目前個人用到的最實用的功能僅僅是避免部分強制類型轉換
因為要擦除,所以無法特化,只能使用繼承加執行個體化類比,徹底扼殺根據實參類型進行自動指派的一切想法
因為要擦除,所以與型別參數(TypeVariable)有關的一切運行期計算,如強制類型轉換,都毫無意義
要想在泛型類方法裡調用型別參數(TypeVariable)的某個業務方法,則型別參數必須<? extends SomeSuper>,一個推論就是<? extends MarkerInterface>在<MarkerInterface>面前毫無意義
諷刺的是,擺明了將問題扔給編譯器解決,編譯器卻除了幫你強轉,塞些TypeVariable資訊外幾乎沒幹什麼事
而Class.forName()後,一切都不安全了
6,基於傳回值的類型推導
不知算不算“擦除法”帶來的特性
例一、Collections.emptyXXX()
emptyList
public static final <T> List<T> emptyList()
-
Returns the empty list (immutable). This list is serializable.
This example illustrates the type-safe way to obtain an empty list:
List<String> s = Collections.emptyList();
Implementation note: Implementations of this method need not create a separate List object for each call. Using this method is likely to have comparable cost to using the like-named field. (Unlike this method, the field does not provide type safety.)
-
-
Since:
-
1.5
-
See Also:
-
EMPTY_LIST
例二、一步一次推導
但如果其傳回值用於另外一個函數的泛型參數,則必須用臨時變數過渡一下,可能是因為不能同時進行兩步推導
public class ConditionParser {
private ConditionParser(){
}
public static <T> Condition<T> deserialize(String condition){
....
}
}
List< Condition<T> > conditions = new ArrayList< Condition<T> >();
Condition<T> safe = ConditionParser.deserialize(condition.ToXML());
conditions.add(safe);//ok
List< Condition<T> > conditions = new ArrayList< Condition<T> >();
conditions.add(ConditionParser.deserialize(condition.ToXML()));//error
7,型別安全的Varargs
其實是數組的簡寫形式,因此是型別安全的,帶來方便的同時,尚未發現有什麼副作用
8,serialVersionUID
到今天了還用實現來暴露意圖,殆也,用Annotation來實現也比現在順眼一點,眼睜睜的看著它混在業務資料對象中
9,物件導向的enum
區別於C++中的enum,J2SE 5.0中的enum是符合“UML有限子類”情形的物件導向的實現(儘管看起來像“有限執行個體”):可以實現介面,可以有建構函式,可以有方法,成員,除了不能繼承和被繼承,建構函式必須私人,其它的和普通Java類差不多
(to be continue...)
(The Java Programming Language Notes )