List.of(123, "hoge")がどんな型になるかを見てみたら、きっとList<Object>になっていて「Objectはどんな値にも対応するんですよー」みたいな説明ができると思っていたら、実際は泣くほど怖い型が出てきた。
List.of(123, "hoge")がどんな型になってるか見ると「Objectは何でも扱えるんですよー」みたいな説明ができるかなと思ったら、泣くほど怖い型が出てきた・・・ pic.twitter.com/Y31F8cdzGH
— きしだൠ(K1S) (@kis) 2021年6月23日
`List<Serializable&Comparable<? extends Serializable&Comparable<?>&java.lang.constant.Constable&java.lang.constant.ConstantDesc>&java.lang.constant.Constable&java.lang.constant.ConstantDesc>
という型になっている。

パッケージ名が邪魔くさいので消してみると
List<Serializable&Comparable<? extends Serializable&Comparable<?>&Constable&ConstantDesc>&Constable&ConstantDesc>
となる。 Genericsは怖いのでComapableのGenericsを消してみるとこんな感じ。
List<Serializable&Comparable&Constable&ConstantDesc>
だいぶ怖くなくなった。
ところで、ConstableとかConstantDescってなんだ?知らない子ですね。
これはJava 12で導入されたConstant APIのインタフェース。
JEP 334: JVM Constants API
Java 11であればこんな感じになる。
jshell> List.of(123, "test") $1 ==> [123, test] jshell> /v $1 | List<Serializable&Comparable<? extends Serializable&Comparable<?>>> $1 = [123, test]
これならわりと怖くない。
ComparableのGenericsを取り除くとList<Serializable&Comparable>となって、これなら付き合ってあげていいかなという気持ちになる。こうやってインラインで書ける。
ところでJava 12以降でも、LocalDateなどとの組み合わせであれば怖くない型になる。
jshell> List.of(123, LocalDate.now()) $2 ==> [123, 2021-06-24] jshell> /v $2 | List<Serializable&Comparable<? extends Comparable<?>>> $2 = [123, 2021-06-24]
LocalDateにはリテラルがないからConstant Poolに入ることがないのでConstableなどが付かないんだろうか。Comparableの中にSerializableがないのもよい。
あと、Streamとの組み合わせであれば望み通りList<Object>が得れる。
jshell> List.of(123, Stream.of()) $3 ==> [123, java.util.stream.ReferencePipeline$Head@5ef04b5] jshell> /v $3 | List<Object> $3 = [123, java.util.stream.ReferencePipeline$Head@5ef04b5]
しかし値がな。