質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

2回答

4831閲覧

ArrayクラスのnewInstanceメソッドの使い方

退会済みユーザー

退会済みユーザー

総合スコア0

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2016/09/26 12:47

JavaのArrayクラスのnewInstanceメソッドの使い方についての質問です。

Java

1public static Object newInstance(Class<?> componentType, 2 int... dimensions) 3 throws IllegalArgumentException, 4 NegativeArraySizeException

「指定されたコンポーネント型と大きさで新しい配列を作成します。componentType が配列でないクラスまたはインタフェースを表す場合、新しい配列の大きさは dimensions.length、コンポーネント型は componentType です。componentType が配列クラスを表す場合、新しい配列の次元数は、dimensions.length および componentType の次元数の合計です。この場合、新しい配列のコンポーネント型は componentType のコンポーネント型です。」

上の文章の前半部分は理解できるのですが、後半部分の使い方がよくわかりません。
おそらく、実際の例を見ればわかると思うのですが、いろいろ調べてみたのですが、後半部分の例は出てきませんでした。
コンポーネント型が配列クラスを表す場合、どのようなコードになるのでしょうか?
回答お願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

           

投稿2016/09/26 16:09

編集2016/09/29 15:04
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/09/27 09:13

非常に初歩的な質問だとは思うのですが、私が実際にnewInstanceメソッドを見たのは次のような例です。 int[] p = (int []) Array.newInstance(int.class, 10); 実際、APIリファレンスの引数を見ましても、引数はClass<?>とintではないでしょうか?(intの方は可変長引数ですが) sipadan2003さんは引数に配列を指定していますが、なぜ可能なのでしょうか?
退会済みユーザー

退会済みユーザー

2016/09/29 15:04 編集

(deleted)
退会済みユーザー

退会済みユーザー

2016/09/28 02:13

回答ありがとうございました。
退会済みユーザー

退会済みユーザー

2016/09/29 15:05 編集

(deleted)
guest

0

ベストアンサー

次元が追加されます。int[].classのint[]を仮にXとし、Xの配列を作ると考えれば納得します。

Java

1Array.newInstance(int[].class, new int[]{3,0}); 2Array.newInstance(int[][].class, 3);

上のコードはどちらも、int[][][]配列を作成し、int[][][].length は 3 です。つまり一次元の要素数が引数で指定した 3 です。引数は int[]{3,0} なので二次元目のサイズが 0 ですが、これはダミーです。Array.newInstance()では、一次元目の要素数だけに意味があり、一次元の要素を持つ参照型の配列が実際にヒープに割り当てられます。

以下のように、1次元の各要素に、それぞれ要素数の異なる2次元配列を割り当てることができます。

Java

1Object o = Array.newInstance(int[].class, new int[]{3,0}); 2int[][][] v = (int[][][])o; 3System.out.println(v.length); 4 5v[0] = new int[5][]; 6v[1] = new int[30][]; 7v[3] = new int[15][];

多次元配列は、以下のように異なるサイズの配列を宣言時に割り当てられます。

Java

1int[][][] v = { 2 { 3 {1,2,3}, 4 {4,5,6,7}, 5 {8,9,10,11,12}, 6 {13,14,15,16,17}, 7 }, 8 { 9 {18}, 10 {19,20}, 11 {21,22,23}, 12 {24,25,26,27}, 13 {28,29,30,31,32}, 14 } 15};

配列は次元ごとに初期化できるからです。

###誤りの訂正
指定した次元はすべて初期化されます。上の例では、3, 0 は正しく二次元まで初期化されます。配列の初期化と配列の要素に代入可能なこととを混同した説明になっています(恥だ)。できれば、Javaのソースコードを調べて回答します。

###訂正
java.lang.reflect.Array のソースコード(build 1.8.0_92-b14)を確認しました。newInstance()から以下のnativeメソッドを呼びます。nativeメソッドの詳細は不明です。

Java

1private static native Object newArray(Class<?> componentType, int length) 2 throws NegativeArraySizeException; 3 4private static native Object multiNewArray(Class<?> componentType, int[] dimensions) 5 throws IllegalArgumentException, NegativeArraySizeException;

配列の中身を確認しました。かっこ悪く力づくでダンプするやり方。

Java

1static void dump(Object o) { 2 System.out.println("---------------"); 3 dump("",o); 4} 5static void dump(String indent, Object o) { 6 if (o == null) { 7 System.out.println("null"); 8 return; 9 } 10 Class<?> cz = o.getClass(); 11 if (cz == int[].class) { 12 dump(indent + " ", (int[]) o); 13 } else if (cz.isArray()) { 14 Object[] o1 = (Object[]) o; 15 System.out.println( 16 "type is " + cz.getTypeName() + " : length = " + o1.length 17 ); 18 for (int i=0; i<o1.length; ++i) { 19 System.out.print(indent+" [" + i + "] : "); 20 dump((indent+" "), o1[i]); 21 } 22 } else { 23 System.out.print(indent + cz.getTypeName() + " : " + o + " "); 24 } 25} 26 27static void dump(String indent, int[] o1) { 28 System.out.print( 29 "type is " + o1.getClass().getTypeName() 30 ); 31 System.out.print(" {"); 32 for (int i=0; i<o1.length; ++i) { 33 System.out.print(((i==0)?"":",") + o1[i]); 34 } 35 System.out.println("}"); 36}

配列の作成とダンプ。指定した次元はすべて初期化されます。

Java

1Object o = Array.newInstance(int[].class, new int[]{5, 2}); 2dump(o); 3 4o = Array.newInstance(int[][].class, new int[]{5}); 5dump(o);

実行結果


type is int[][][] : length = 5
[0] : type is int[][] : length = 2
[0] : null
[1] : null
[1] : type is int[][] : length = 2
[0] : null
[1] : null
[2] : type is int[][] : length = 2
[0] : null
[1] : null
[3] : type is int[][] : length = 2
[0] : null
[1] : null
[4] : type is int[][] : length = 2
[0] : null
[1] : null


type is int[][][] : length = 5
[0] : null
[1] : null
[2] : null
[3] : null
[4] : null

投稿2016/09/26 14:51

編集2016/09/26 18:37
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/09/26 15:49 編集

「一次元目の要素数だけに意味があり」とありますが、 次のコードをJava 8で実行してみたところ、2次元目の要素数も意味を持つようです。 Object[][] aa = (Object[][])Array.newInstance(String.class, new int[]{5, 2}); System.out.println(Arrays.deepToString(aa));
退会済みユーザー

退会済みユーザー

2016/09/26 16:19

確認しました。二次元目も配列の要素がnull初期化されいます。初期化されていたものを、代入して置き換えられることとと混同しています。詳しく調べて訂正します。ありがとうございました。
退会済みユーザー

退会済みユーザー

2016/09/28 02:13

わかりやすく例まであげていただきありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問