1

If the only element of the type Void is null, and null is an element of every reference type in Java, why is Void not considered a subtype of every reference type? Other than legacy, are there reasons why Void should not be the bottom type in Java?

Note: I'm looking for a design justification (if there is one), not just "because the JLS says so".


Potential use case: empty collections

A typical use case for the bottom type is to type an empty list. Given two unrelated classes A and B, consider the following two method signatures.

float processAs(List<? extends A> as) { ... }
float processBs(List<? extends B> bs) { ... }

Note that I made the list parameters 'covariant' using a wildcard. Now, for some list List<C> cs where C is any subtype of A, I'm still able to call processAs(cs). (analogously for processBs) Suppose now that we have an empty list List<...> empty = Collections.emptyList();. Depending on which type I fill in for the dots, I can call processAs when it is a subtype of A or call processBs when it is a subtype of B, but not both. Yet, nothing unsafe can happen if I would be able to pass it to both. If Void was considered the bottom type, we could type it as List<Void> and I could write processAs(empty) and processBs(empty) with no problem.

This would work much like the Nothing type in Scala, where lists are considered covariant too.


A bit of context

I'm writing a code translator from a language called Nouga (not released yet) to Java. In Nouga, there is a bottom type called nothing. The Void type seemed the most appropriate translation for that. Although I can work around the mistranslation of the subtype relation using coercions, it still made me curious whether there are reasons why Void should not be considered the bottom type.


Possibly related: Why is void not covariant in Java? But this questions seems to be more about a confusion between covariance and contravariance (i.e., the OP uses void as if it were the top type, not the bottom type).

Safron
  • 802
  • 1
  • 11
  • 23
  • This statement about Scala's `Nothing`: _...at the bottom of Scala's type hierarchy_ seems misleading since Scala's `Nothing` extends Scala's `Any`. So which is really the bottom type? From a java perspective since `Void` represents, well, void, it doesn't make sense (at least to me) to extend from java's `Void` (let alone it be java's bottom type). Perhaps Nouga'a `Nothing` is akin to java's `Object` rather than java's `Void`. – Andrew S Jan 06 '22 at 19:04
  • 2
    @AndrewS Thanks for the comment. I think there is some confusion though. Three remarks. (1) `Any` is the top type in Scala, so as any other type, the bottom type `Nothing` extends from it. (2) From a Java prespective, you would indeed *not* extend `Void`; rather `Void` would be an extension of everything. That's what it means to be the bottom type. (3) `Object` in Java is the top type, so that actually corresponds to Scala's `Any` type. In Nouga there is no top type. – Safron Jan 06 '22 at 19:14

0 Answers0