List.of(123, "hoge")
がどんな型になるかを見てみたら、きっとList<Object>
になっていて「Objectはどんな値にも対応するんですよー」みたいな説明ができると思っていたら、実際は泣くほど怖い型が出てきた。
`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]
しかし値がな。