this post was submitted on 14 Jun 2023
15 points (100.0% liked)

Java

1394 readers
13 users here now

For discussing Java, the JVM, languages that run on the JVM, and other related technologies.

founded 1 year ago
MODERATORS
 

A great read for folks wondering why Java uses type erasure instead of "reified" generics. For the unaware, that means that a List<Integer> is a List<Object> at runtime. I had always wondered about it and why they didn't take the alternative route. For context, C# does have reified types so the actual type parameter is available at runtime.

I personally love reading in depth discussions about counter intuitive engineering decisions like this.

you are viewing a single comment's thread
view the rest of the comments
[–] [email protected] 3 points 1 year ago (7 children)

I've always wondered, if it's also just less pain when you write plain/idiomatic Java.

I write mostly functional Scala with lots of message passing and such, so data types often move through interfaces where their type may be lost and then we do lots of pattern matching, where missing runtime types come up on quite a regular basis.

I'd say probably once a week, I have to write or come by an ugly portion of code where we had to manually pass around type information and do explicit casts to make it all fit together.

[–] JackbyDev 1 points 1 year ago (6 children)

I'm not familiar with Scala, but doesn't it have a different form of generic typing? Like isn't there a way to explicitly say if you want co- or contravariance? Maybe it's not totally compatible.

But yeah, even as an exclusive Java developer the only time I have to do something like this is when you're doing something like deserializing JSON and need a type parameter. As an example you can tell it, "Hey, I expect this is LocalDate.class" but if you need something like a List<LocalDate> you can't do that with the .class syntax. Weirdly, anonymous inner classes do store type parameters so the way most frameworks handle it is something like new TypedParamter<List<LocalDate>> {}. I'm not sure if there is a way for frameworks to get around it, I just know that's the only real time I see it.

[–] [email protected] 2 points 1 year ago (5 children)

Scala does have a way of specifying co-/contravariance, but Java actually does have that, too. In Java, you write <? extends T> for covariance and <? super T> for contravariance. Well, and generally, Scala's generics are compatible with Java's. It's quite common to use Java libraries in Scala.

One example where type erasure causes problems (which should be the same in Java):
Imagine, you're managing sensors and all of those sensors have a generic to remember what element will be produced by them: Sensor, Sensor etc.
If you want to keep all of those Sensors in one big list/map, you end up with a Sensor when you take them back out.

To retain type information, you have to put them into individual lists or somehow place a runtime type next to each element in the list, from which you can determine what to cast to.

I guess, in languages without type erasure, it doesn't let you place a Sensor into the same list as a Sensor to begin with, as those are strictly different types.
But of course, those languages may offer ways of doing type erasure anyways, and obviously, you can fall back to a common interface/supertype, if the types have that.

[–] kaba0 1 points 1 year ago

Note that Java’s generics are on the library-side, while Scala’s is defined at use site.

load more comments (4 replies)
load more comments (4 replies)
load more comments (4 replies)