1

私が怠け者だとしましょう。

vvriting の長い System.out.println() の代わりに、次のようなメソッドを作成します。

public static void println(Object ... o) {

    if (o.length == 0)
        System.out.println();
    else for (Object obj : o)
        System.out.println(obj);
}

novv vvhen 私は belovv のように使います。

String[] s = {"hello", "vvorld"};
println(s);

それは印刷します:

hello
vvorld

しかし、このメソッドをプリミティブ データ型で使用する場合、たとえば、

int[] i = {1 ,2};
println(i);

ガベージ値を出力します!

ヴィヴィ?

ここで渡したのは OBJECT 配列ではなく、PRIMITIVE DATATYPE 配列だからです。


それでは、上記のメソッドをそのままにして、「int」型の引数用の別のメソッドを作成しましょう。

public static void println(int ... o) {

    if (o.length == 0)
        System.out.println();
    else for (int obj : o)
        System.out.println(obj);
}

私が使用する両方の方法を持っている novv

int[] i = {1 ,2};
println(i);

それは言う:

error: reference to println is ambiguous, both method println(int...) and method println(Object...) match

Q-1:

novv hovv 一方がオブジェクトで、もう一方が int|プリミティブ データ型の場合、この呼び出しを解決できませんか?

A-1:

Que に障害があります。「int」ではなく「int[]」オブジェクトであるため、次のようなメソッドがあった場合に (Object...) または (int...) を呼び出すかどうかがあいまいです。 void println(int o) { ... ... } あいまいさはありません。

Q-2:

int 型の配列を渡したからですか?

A-2:

int[] が原因です。これは、int 配列を引数として受け入れることができるメソッド、つまり (int...) Version as vvell があるためです。配列オブジェクトを引数として受け入れることができるメソッド、つまり (Object. ..) バージョン

Q-3:

配列はオブジェクトであることを理解できます。したがって、両方のvvaysになりますが、vvhen int []のより具体的に定義されたメソッドが存在する場合、それはresolVableである必要はありませんか?

A-3:

もちろん、より具体的なバージョンがある場合は、たとえば betvveen belovv giVen 2 のように vvill を呼び出す必要があります。文字列バージョンは int xyz(String s) { ... } int xyz(Object o) { ... } と呼ぶ必要があります。

Q-4:

プリミティブ データ型の配列の各要素をオブジェクトとして vvell として println() する vvay を使用できますか?

A-4:

はい、私はそれをbelovvとして発見しました:

public static void println(Object ... o) {

    for (Object obj : o)
        System.out.println(obj);
}

public static void println(int[] o) {

    for (int obj : o)
        System.out.println(obj);
}

アップデート :

すみません、私のミスです。

println(1, 2); のエラーメッセージが表示されました。println(i) ではありません。// hovv地球上で、エラーの行番号が表示されませんでした!!!

しかし、それはまた、nevvの疑いを生み出しました....

このコードを見てください..

class demo {

public static void println(Object ... o) {

    System.out.println("Object...");

    for (Object obj : o)
        System.out.println(obj);
}

//public static void println(int[] o) { // method-1
public static void println(int ... o) { //method-2

    System.out.println("int...");

    for (int obj : o)
        System.out.println(obj);
}

public static void main(String[] args) {

    int i[] = {1 ,2};
    println(i); //this vvorks fine
    println(new int[] {1, 2}); //this vvorks fine
    println(3, 4); //this raises compile-time-error of ambiguous call
}

}

method-2 の代わりに "method-1" を使用した場合の novv

内...

1

2

内...

1

2

物体...

3

4

ここでのnevvの質問は次のとおりです。

vvhy vvould not method-2 just vvork for last statement ?

そして、vvhy は method-1 に対して vvork しますか?

最後のステートメントが生成するメソッド-1を使用するvvhen:

物体...

1

2

vvhich は私には「理解できない」ので、そのためには println(Object... を呼び出す必要があり、渡された引数がオブジェクトとして動作する場合、1 つの状況でのみ呼び出すことができます。

ここに存在できる唯一のオブジェクトは、vve が「int 配列」を持っていることです。

それが int 配列、つまり {3, 4} の場合、その要素はオブジェクトではなく整数です

それらがプリミティブなデータ型である場合、 hovv は「for (Object obj : o)」 vvork できますか?

助けてくれてありがとう:)

4

5 に答える 5

3

署名public static void println(Object ... o)は実際には普通の古いObject[]. に...変わる構文シュガーを許可するようにコンパイラに指示するだけです。ただし、引数として を受け取るだけなので、 を渡すだけの非構文糖形式で呼び出すこともできます。println("hello", "world")println(new String[]{"hello", "world"})Object[]Object[]

String[]は のサブクラスであるObject[]ため、 を渡すString[]と、糖以外の形式として解釈されます。一方、int[]はオブジェクトではなくプリミティブであるためObject[]、のサブクラスではありません。intしたがって、呼び出し砂糖フォームをトリガーします。あなたが実際にしていることはそこにありint[] i = {1, 2}; println(new Object[] { i })ます。

Java の配列には適切な文字列表現がありませんObject.toString。オブジェクトのクラスと参照のハッシュを出力するデフォルトの を使用するだけです。

編集:

@Rohit Jain は、「println への参照があいまいです」というエラーは発生しないと指摘しており、javac で確認しました。この例を参照してください。

于 2013-08-06T15:02:23.777 に答える
1

あなたが持っている

public static void println(Object ... o) {

public static void println(int ... o) {

これらのメソッドのいずれかint[]が引数に適用されます。最初の例では、配列全体が単一のオブジェクトとして扱われ、単一の引数として渡されます。2 つ目は、配列の内容が可変引数自体として扱われます。

あなたが持っているとしましょうint[] v = {a,b,c}。最初のメソッドはprintln(v)( vis であるため) として呼び出すことができますが、int 配列は int varargs と互換性があるためObject、2 番目のメソッドはとして呼び出すこともできます。println(a,b,c)

ここにはあいまいさがあり、コンパイル エラーが発生します。

ここで、前の質問に対処します。

ガベージ値を出力します!なぜ ?

int[]説明したように、 を引数付きのメソッドに渡すと、配列が1 つのオブジェクトObject ...として扱われ、配列はオーバーライドされないためです。toString()


余談ですが、 を参照してくださいArrays.toString()

于 2013-08-06T14:52:33.390 に答える
0

これは便利だと思うかもしれません。これはatをObject[1]含む を取り、それを に変換します。私はあなたの質問を理解したと思います.int[][0]Integer[]

/**
 * Can rebox a boxed primitive array into its Object form.
 * 
 * Generally I HATE using instanceof because using it is usually 
 * an indication that your hierarchy is completely wrong.
 * 
 * Reboxing - however - is an area I am ok using it.
 *
 * Generally, if a primitive array is passed to a varargs it
 * is wrapped up as the first and only component of an Object[].
 *
 * E.g.
 *
 * public void f(T... t) {};
 * f(new int[]{1,2});
 *
 * actually ends up calling f with t an Object[1] and t[0] the int[].
 *
 * This unwraps it and returns the correct reboxed version.
 *
 * In the above example it will return an Integer[].
 *
 * Any other array types will be returned unchanged.
 *
 * @author OldCurmudgeon
 */
public class Rebox {
  public static <T> T[] rebox(T[] it) {
    // Default to return it unchanged.
    T[] result = it;
    // Special case length 1 and it[0] is primitive array.
    if (it.length == 1 && it[0].getClass().isArray()) {
      // Which primitive array is it?
      if (it[0] instanceof int[]) {
        result = rebox((int[]) it[0]);
      } else if (it[0] instanceof long[]) {
        result = rebox((long[]) it[0]);
      } else if (it[0] instanceof float[]) {
        result = rebox((float[]) it[0]);
      } else if (it[0] instanceof double[]) {
        result = rebox((double[]) it[0]);
      } else if (it[0] instanceof char[]) {
        result = rebox((char[]) it[0]);
      } else if (it[0] instanceof byte[]) {
        result = rebox((byte[]) it[0]);
      } else if (it[0] instanceof short[]) {
        result = rebox((short[]) it[0]);
      } else if (it[0] instanceof boolean[]) {
        result = rebox((boolean[]) it[0]);
      }
    }
    return result;
  }

  // Rebox each one separately.
  private static <T> T[] rebox(int[] it) {
    T[] boxed = makeTArray(it.length);
    for (int i = 0; i < it.length; i++) {
      boxed[i] = (T) Integer.valueOf(it[i]);
    }
    return boxed;
  }

  private static <T> T[] rebox(long[] it) {
    T[] boxed = makeTArray(it.length);
    for (int i = 0; i < it.length; i++) {
      boxed[i] = (T) Long.valueOf(it[i]);
    }
    return boxed;
  }

  private static <T> T[] rebox(float[] it) {
    T[] boxed = makeTArray(it.length);
    for (int i = 0; i < it.length; i++) {
      boxed[i] = (T) Float.valueOf(it[i]);
    }
    return boxed;
  }

  private static <T> T[] rebox(double[] it) {
    T[] boxed = makeTArray(it.length);
    for (int i = 0; i < it.length; i++) {
      boxed[i] = (T) Double.valueOf(it[i]);
    }
    return boxed;
  }

  private static <T> T[] rebox(char[] it) {
    T[] boxed = makeTArray(it.length);
    for (int i = 0; i < it.length; i++) {
      boxed[i] = (T) Character.valueOf(it[i]);
    }
    return boxed;
  }

  private static <T> T[] rebox(byte[] it) {
    T[] boxed = makeTArray(it.length);
    for (int i = 0; i < it.length; i++) {
      boxed[i] = (T) Byte.valueOf(it[i]);
    }
    return boxed;
  }

  private static <T> T[] rebox(short[] it) {
    T[] boxed = makeTArray(it.length);
    for (int i = 0; i < it.length; i++) {
      boxed[i] = (T) Short.valueOf(it[i]);
    }
    return boxed;
  }

  private static <T> T[] rebox(boolean[] it) {
    T[] boxed = makeTArray(it.length);
    for (int i = 0; i < it.length; i++) {
      boxed[i] = (T) Boolean.valueOf(it[i]);
    }
    return boxed;
  }

  // Trick to make a T[] of any length.
  // Do not pass any parameter for `dummy`.
  // public because this is potentially re-useable.
  public static <T> T[] makeTArray(int length, T... dummy) {
    return Arrays.copyOf(dummy, length);
  }
}

その後、次のように使用できます。

public StringBuilder add(StringBuilder s, T... values) {
  // Remember to rebox it in case it's a primitive array.
  for (T v : Rebox.rebox(values)) {
    add(s, v);
  }
  return s;
}
于 2013-08-06T15:12:57.650 に答える
0
System.out.println(Arrays.toString(myArray));
于 2013-08-06T14:52:12.413 に答える