[Java] Type Erasure: Implement the Interface with Two Generic Types

在 Java 實作擁有 Generic Type 的 Interface 時,可能會希望同時 implement 兩種不同 Type 的 Interface。

狀況如下,有個 class 需要接收兩種不同的 Future Task 結果,
– 要被 implement 的 interface
 
public interface FutureListener<T> {
public void onFutureDone(T future);
}
– 要實作 interface 的 class
 
public class Service implements
FutureListener<int> futureA, FutureListener<String> futureB { /// type erasure

public void onFutureDone(Future<int> future) { }
public void onFutureDone(<String> future) {}
}
可惜的是,因為 type erasure,這樣的實作方式是不被接受的。
  • 那…… 什麼是 type erasure 呢?
Oracle 的 Java Tutorials 內可以找到討論 type erasure 的條目,摘錄如下,
When a generic type is instantiated, the compiler translates those types by a technique called type erasure — a process where the compiler removes all information related to type parameters and type arguments within a class or method. Type erasure enables Java applications that use generics to maintain binary compatibility with Java libraries and applications that were created before generics.
在 compile-time 時,Compiler 會移除 type parameter 及 type argument,藉此達成 Generic 目的,又
For instance, Box<String> is translated to type Box, which is called the raw type — a raw type is a generic class or interface name without any type arguments. This means that you can’t find out what type of Object a generic class is using at runtime.
由此可知,在 run-time 時,會因為 compiler 把 type parameters & arguments 去除掉,使得 List<int> 及 List<String> 沒辦法被表現出差異,如此會導致 JVM 無法認清不同 type 的 object。
  • 如果有 type erasure,那 T type 如何被操作?
Compiler 會幫忙作 casting,因而達到 Generic。各位可以參考 Angelika Langer 的網站,針對 Type Erasure 有詳盡的描述及範例。
  • 該怎麼解決這個問題?
可以透過實作兩個 inner class 來解決這個問題,
 
public class Service {
@Override
private class FutureA implements FutureListener<int> {
public void onFutureDone(Future<int> future) { }
}

@Override
private class FutureB implements FutureListener<String> {
public void onFutureDone(Future<String> future) { }
}
}
  • 結論
在使用 Java 的 Generic 特性時,看來還是得先理解 Type Erasure,才能避免一些實作上的問題。透過這樣的 Survey 後,發現 Java 其他有趣的部份,一時半刻要弄熟也不是簡單的事情,還有很多需要學習的部份,一想到這邊就感受到渾身的熱情,有幸能夠接觸這些技術真是太好了。
Reference:

發佈留言