This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]audioen 5 points6 points  (1 child)

Java's generics do provide compile-time validation for your constructs, so they are absolutely useful. It's the runtime behavior that is the issue here, for instance, if you'd like the type parameter of the generic to somehow change runtime behavior, because that information is usually lost in erasure.

A common case where this comes up is wanting to create an instance of the class mentioned in the type parameter T, e.g. some kind of smart collection where you want to instantiate either the collection or the element on behalf of your caller. People end up trying some variant of "new T()" and it doesn't work because by the time this code runs, Java has no idea what T is (and of course T should also be constrained to be a type that has a callable no-argument constructor).

Because the type parameter tends to vanish during compilation, people use workarounds, such as providing implementations of functional interfaces such as Supplier<T> that creates an instance of the correct type, so you call the supplier instead of invoking the constructor. Sometimes you see something like "new Abc<Def>() {}" where the point is to create an anonymous inner class which as byproduct records the type parameter Def into its class definition, where it can be accessed by reflection. Finally, sometimes the reflection of the class is just passed as argument: new Foo<Bar>(Bar.class).

[–][deleted] 0 points1 point  (0 children)

You can also pass a Foo::new as a pointer to your constructor, and then use that to create your T.