An example, let's say we have a Greetable interface
interface Greetable<T> { String hello(T another); }
On non-generics-capable Java, e.g. developers using JVM 1.4 or earlier, shall see Greetable's hello method's parameter as:
Type erasure has some problems though. Let's say you have two classes Geek and Hipster that implements the same interface, yet they can be friendly only among their own kind, this is where type erasure can be a problem. Read on.
class Hipster implements Greetable<Hipster> { String _name; Hipster(String name) { _name = name; } @Override public String toString() { return _name; } @Override public String hello(Hipster another) { return "Hi I'm " + _name + ", hola mi amigo " + another + "!"; } } class Geek implements Greetable<Geek> { String _name; Geek(String name) { _name = name; } @Override public String toString() { return _name; } @Override public String hello(Geek another) { return "Hi I'm " + _name + ", charie " + another + "!"; } }
You can see that both of them implements method hello, yet their accepted parameter is confined only to their own kind. This is where generics shine, error(type mismatches) can be caught during compile-time, not when it is costly to fix an error(during runtime)
Given this:
Hipster george = new Hipster("George"); Geek paul = new Geek("Paul");
Then you do this:
george.hello(paul); // compile error
That will not be allowed by the compiler, that will result to compile-time error. You use generics if you want to enforce types compatibility. Compiler can catch this error
// this is allowed. Hipster is derived from Greetable Greetable<hipster> george = new Hipster("Pete"); Geek paul = new Geek("Paul"); // but this will not be allowed. george.hello(paul);
george.hello method signature is hello(Hipster another);. Paul is not a Hipster, he's a Geek, hence the compiler can catch that Paul doesn't matched George's friend preference of Hipster.
With type erasure, type mismatches are not caught by the compiler:
// this is allowed. Hipster is derived from Greetable Greetable george = new Hipster("George"); george.hello(paul); // this will be allowed by the compiler. yet this will throw an exception during runtime
With type erasure, the type on george's hello method became an untyped one, it has method signature of hello(Object another). This has the consequence of the compiler not being able to catch type mismatches for you, hence the type incompatibility just arises during runtime only, the runtime will throw an exception; which is bad, it's better to fix errors earlier.
No comments:
Post a Comment