配列リテラルっぽいものを考えてたら、「プリミティブ型配列は使っちゃなんねー」という結論に行き着いた
Rubyで配列リテラルが書けるのは、型無しの言語だから。MLでリストリテラルが書けるのは、型推論があるから。
Javaの配列リテラルで彼女ができた - soutaroブログ
じゃぁ、型推論させればいいのね。ということで、ちょっと試した。
String[] strings = new String[]{"a", "b", "c"};
これが、
String[] strings = array("a", "b", "c");
短くなったね!ちょっとだけどね!
コードやケースは下記の通りとして、重要な結論は「プリミティブ型配列は使っちゃなんねー」でした。
import static java.lang.System.out; public class Hoge { public static <V> V[] array(V...values){ return values; } public static void main(String[] args) { // 普通に。 out.println(array("a", "b", "c").getClass()); // => class [Ljava.lang.String; out.println(array("a", "b", "c")[0]); // => a // プリミティブ型はラッパークラスとして扱う。 out.println(array(1, 2, 3).getClass()); // => class [Ljava.lang.Integer; out.println(array(1, 2, 3)[0]); // => 1 // 推論できる型が複数あれば、warning扱いとなる。 // Type safety : A generic array of Object&Comparable<?>&Serializable is created for a varargs parameter out.println(array(1, "b", "c").getClass()); // => class [Ljava.lang.Comparable; // その場合、型パラメータを明示することで回避はできる。けど、長くてだれもやらないと思う。 out.println(Hoge.<Object>array(1, "b", "c").getClass()); // => class [Ljava.lang.Object; // 配列でパラメータを与えた場合、そのオブジェクトそのものが返る。 String[] strings = new String[] {"foo", "bar"}; Object[] objects = array(strings); out.println(objects == strings); // => true strings[0] = "hoge"; out.println(objects[0]); // => hoge // objectsのクラスはString[]なのでStringクラス以外は格納できないが、 // 下記は静的チェックでは検出されず、実行時例外となる。 // objects[0] = 1; // Exception in thread "main" java.lang.ArrayStoreException: java.lang.Integer // 一見、プリミティブ型の配列をオブジェクトの配列に変換出来たりするが…。 int[] ints = new int[] {1, 2, 3}; Object[] objects2 = array(ints); out.println(objects2.getClass()); // => class class [[I // でも、中身はぐちゃぐちゃ。ありえない。 out.println(objects2[0]); // => [I@ca0b6 out.println(objects2[0].equals(1)); // => false // out.println(objects2[0] == 1); // コンパイルエラー : Incompatible operand types Object and int // 配列オブジェクト同士の==演算すらできない。 // out.println(objects2 == ints); // コンパイルエラー : Incompatible operand types Object and int } }