概要: 基本型配列を引数にしてかつ様々な型に対応させたい
あまり需要ないかもしれませんが書いておきます。
Javaのプログラムで、あるメソッドの引数を数値基本型の配列で定義するとします。
ただし処理の内容は型によらず同じであり(例えば以下の様な文字列結合)、かつ実際には各要素にintが来るのかdoubleが来るのかわからない場合、果たしてどのようにメソッドを定義すればよいでしょうか。
例えば型に合わせてオーバーロード(多重定義)することにより対応させられるかもしれません。
/*
* 以下の3つのメソッドはこのままだと1つにはまとめられない
*/
// int型配列用
public void concatArray(int[] num) {
String line = "";
for(int i : num) line += i + ",";
System.out.println(line.substring(0, line.length() - 1));
}
// double型配列用
public void concatArray(double[] num) {
String line = "";
for(double d : num) line += d + ",";
System.out.println(line.substring(0, line.length() - 1));
}
// float型配列用
public void concatArray(float[] num) {
String line = "";
for(float f : num) line += f + ",";
System.out.println(line.substring(0, line.length() - 1));
}
しかしこれを見て、『基本型に合わせてわざわざ多重定義する必要はない!!』と思った方はお気づきかもしれませんが**Number
型にBoxingしてしまう**という方法があります。
Number
はInteger
やDouble
の親クラスで、型が不明な数値配列もまとめて扱うことができます。
private String concatArray(Number[] numbers) {
String line = "";
for (Number number : numbers)
line += number.toString() + ",";
System.out.println(line.substring(0, line.length() - 1));
}
さらに数値以外の引数が来るなら、より抽象度を上げてObject
配列を引数にする必要もあるでしょうが、数字だけであればNumber
で十分かと思われます。また元の数値に戻すメソッド(Number.intValue()
, Number.doubleValue()
)もあります。
ただしNumberを直接new
する時は、抽象メソッドであるNumber.intValue()
やNumber.doubleValue()
の実装が必要です。
Number number = new Number() {
@Override
public int intValue() {
return 0;
}
...
};
余談: そもそもJavaの配列は特殊なクラス
そもそものきっかけは、配列のクラス名が分かれば、共通の親クラスを引数にするメソッドを書くことで、上記の要件を達成できるのではないのかと考えたことでした。
Javaの配列はObject
継承であり、ゆえにObject
から継承されたメソッド群も使えます。しかし次のコードは何を出力するでしょうか?
public class ArrayClassName() {
public static void main(String args[]) {
boolean[] b = { true, false };
int[] i = { 1, 2, 3 };
double[] d = { 1.11, 2.22, 3.33 };
System.out.println(b.getClass());
System.out.println(i.getClass());
System.out.println(d.getClass());
}
}
答えはこうです
class [Z
class [I
class [D
"Array"などと表示してくれるかと思いきや、何やら意味不明な文字列が出力されます。
実はJavaの配列はObject
継承でありながら、どのクラスやパッケージにも属さない特殊なクラスだったのです!
(そんなこと大学の先生は一言も教えてくれなかったよ!!)
なんか言葉だけだと矛盾してしまうようですが本当です。
ではこの意味不明な文字列は何かというと、Javaの言語仕様に
where the string "[I" is the run-time type signature for the Class object "array with component type int".
とあります。
意訳すると**『"[I"は『int型配列』のクラスオブジェクトの実行時型を表すシグネチャである』**となります。
シグネチャはJavaの内部処理的に振らているメソッドの識別コードのようなものですが、それがなぜ配列にフラレているのかまではわかりませんでした。
結局のところ、Javaで厳密に配列がどのような位置づけなのかはわかりませんでしたが、クラスではないObjectというのが今の結論でしょうか。
たぶん間違っていると思いますので、ネットで資料が出てこないので誰か教えて。