JEP 300 - casting with declaration-site variance

Attila Kelemen attila.kelemen85 at gmail.com
Tue Mar 4 19:51:56 UTC 2025


Hi,

I have read JEP 300, and it seems it is not defining what it intends to do
with casting these adjusted types to a subtype. For example consider the
following method:

```
<T> void method1(Iterable<T> itr) {
  if (itr instanceof List) {
    var list = (List<T>) itr;
    list.add(null);
  }
}
```

The cast in the above example is safe (it doesn't emit any unsafe cast
warning). However, if `Iterable` becomes covariant at the declaration site,
then the above code is now unsafe.

What is the plan of the JEP with such casting? Will it make the above cast
unsafe? If so, then there will be no way to safely cast from `Iterable<T>`
to `List<T>`. Admittedly, I can't recall any code I have ever seen where
this would be a problem (and so I wouldn't worry about it too much), but it
would be nice if the JEP would explicitly address this question.

In Kotlin, they allow such unsafe casts without a warning (in fact, you
don't even need a cast in Kotlin for it). For example, the following code
compiles without warning in Kotlin:

```
fun evilMethod(list: List<Any>) {
  if (list is MutableList) {
    list.add("hello")
  }
}

fun naiveMethod() {
  val list = mutableListOf<Int>()
  evilMethod(list)
  println(list.sum())
}
```

Of course, calling `naiveMethod` fails with an exception when trying to
call `sum`. (Note: `List` in Kotlin is a "read-only" variant of Java's
List, and MutableList is the equivalent of Java's List interface).

I personally don't like the behavior of Kotlin, and would rather choose
that only `Iterable<T>` to `List<? extends T>` is safe from here onwards.

Attila
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/compiler-dev/attachments/20250304/9ef9fafd/attachment.htm>


More information about the compiler-dev mailing list