Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do some claim that Java's implementation of generics is bad?

Tags:

java

generics

People also ask

What is the disadvantages of using generics?

Cannot Create Instances of Type Parameters. Cannot Declare Static Fields Whose Types are Type Parameters. Cannot Use Casts or instanceof With Parameterized Types. Cannot Create Arrays of Parameterized Types.

Is it a good idea to use generics in collections?

By using generics, programmers can implement generic algorithms that work on collections of different types, can be customized, and are type safe and easier to read.

Why generics are introduced in Java What problems do they overcome?

To overcome the above problems of collections(type-safety, type casting) generics introduced in java 1.5v . Main objectives of generics are: 1) To provide type safety to the collections. 2) To resolve type casting problems. To hold only string type of objects we can create a generic version of ArrayList as follows.

Why are generics implemented using type erasure?

Generics were introduced to the Java language to provide tighter type checks at compile time and to support generic programming. To implement generics, the Java compiler applies type erasure to: Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded.


Bad:

  • Type information is lost at compile time, so at execution time you can't tell what type it's "meant" to be
  • Can't be used for value types (this is a biggie - in .NET a List<byte> really is backed by a byte[] for example, and no boxing is required)
  • Syntax for calling generic methods sucks (IMO)
  • Syntax for constraints can get confusing
  • Wildcarding is generally confusing
  • Various restrictions due to the above - casting etc

Good:

  • Wildcarding allows covariance/contravariance to be specified at calling side, which is very neat in many situations
  • It's better than nothing!

The biggest problem is that Java generics are a compile-time only thing, and you can subvert it at run-time. C# is praised because it does more run-time checking. There is some really good discussion in this post, and it links to other discussions.


The main problem is that Java doesn't actually have generics at runtime. It's a compile time feature.

When you create a generic class in Java they use a method called "Type Erasure" to actually remove all of the generic types from the class and essentially replace them with Object. The mile high version of generics is that the compiler simply inserts casts to the specified generic type whenever it appears in the method body.

This has a lot of downsides. One of the biggest, IMHO, is that you can't use reflection to inspect a generic type. Types are not actually generic in the byte code and hence can't be inspected as generics.

Great overview of the differences here: http://www.jprl.com/Blog/archive/development/2007/Aug-31.html


  1. Runtime implementation (ie not type erasure);
  2. The ability to use primitive types (this is related to (1));
  3. While the wildcarding is useful the syntax and knowing when to use it is something that stumps a lot of people. and
  4. No performance improvement (because of (1); Java generics are syntactic sugar for castingi Objects).

(1) leads to some very strange behaviour. The best example I can think of is. Assume:

public class MyClass<T> {
  T getStuff() { ... }
  List<String> getOtherStuff() { ... }
}

then declare two variables:

MyClass<T> m1 = ...
MyClass m2 = ...

Now call getOtherStuff():

List<String> list1 = m1.getOtherStuff(); 
List<String> list2 = m2.getOtherStuff(); 

The second has its generic type argument stripped off by the compiler because it is a raw type (meaning the parameterized type isn't supplied) even though it has nothing to do with the parameterized type.

I'll also mention my favourite declaration from the JDK:

public class Enum<T extends Enum<T>>

Apart from wildcarding (which is a mixed bag) I just think the .Net generics are better.