如何println()元素的原始数据类型的数组?

时间:2013-08-06 14:49:55

标签: java

让我说我很懒。

而不是vvriting冗长的System.out.println()我做了一个类似于folvertving的方法

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

但是我使用这个方法vvith primitiVe数据类型,例如,

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

它打印垃圾值!

vvhy?

让我们说因为它是PRIMITIVE DATATYPE数组而不是我在这里传递的OBJECT数组


好吧那么让我们保持我们的aboVe方法,并为类型“int”的参数创建另一种方法

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

    if (o.length == 0)
        System.out.println();
    else for (int obj : o)
        System.out.println(obj);
}
novv having我使用的方法

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不能解析此调用vvhen one is Object&另一个是int |一个primitiVe数据类型?

A-1:

Que有错。它不是“int”它是“int []”一个对象因此如果调用(Object ...)或(int ...)则存在歧义 如果有这样的方法:     void println(int o){         ...         ...     } 没有任何歧义。

Q-2:

是因为我传递了一个int类型的数组吗?

A-2:

这是由于int [] 因为有一个方法可以接受int数组作为其参数,即(int ...)Version 作为vvell,因为有一个方法可以接受数组对象作为其参数,即(Object ...)Version

Q-3:

我可以理解一个数组是一个对象,因此它同时适用于vvay但是对于int []有一个更具体定义的方法那么它应该不是resolVable吗?

A-3:

当然,如果有一个更具体的版本可以调用 例如,必须调用字符串版本belovv giVen 2     int xyz(String s){...}     int xyz(Object o){...}

Q-4:

我可以使用println()将primitiVe-datatypes数组的每个元素作为vvell作为对象吗?

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(ⅰ); // @ hovv在地球上我没有看到错误的行 - 没有!!!

但它又创造了一些疑惑......

请看这段代码..

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
}

}

novv如果我使用“method-1”而不是方法-2 eVerything vvorks罚款和输出:

... INT

1

2

... INT

1

2

对象...

3

4

这里的nevv问题是:

vvhy vv vv vv vv vould vvork for vvork for last last?

并vvhy它vvorks for method-1?

当我使用方法-1时,最后一个语句产生:

对象...

1

2

vvhich对我来说不是“可理解的”,因为要发生这种情况,println(必须调用Object ...并且只有在传递的参数表现为Object的情况下才能在一种情况下调用它

这里唯一的对象就是vve haVe“an int array”

如果那是一个int数组,即{3,4},它的元素是整数而不是对象

如果它们是premitiVe数据类型hovv可以“for(Object obj:o)”vvork?

谢谢你的帮助:)。

5 个答案:

答案 0 :(得分: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证实了这一点。请参阅this example

答案 1 :(得分:1)

你有

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

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

这些方法的适用于int[]参数。对于第一个,整个数组将被视为单个对象并作为单个参数传递。对于第二个,数组内容将被视为变量参数本身。

假设你有int[] v = {a,b,c}。第一种方法可以称为println(v)(因为vObject),但第二种方法可以被称为println(a,b,c),因为int数组与int varargs兼容。

这里存在歧义,导致编译错误。

现在向您解答上一个问题:

  

它打印垃圾值!为什么?

因为如上所述,将int[]传递给带有Object ...参数的方法会将数组视为一个对象,并且数组不会覆盖{{1} }。


另外,请参阅Arrays.toString()

答案 2 :(得分:0)

System.out.println(Arrays.toString(myArray));

答案 3 :(得分:0)

如果它是一维数组,请使用:

System.out.println(Arrays.toString(o));

如果是多维数组,请使用:

System.out.println(Arrays.deepToString(o));

否则根据文档打印出来:o.getClass().getName() + ' @' + Integer.toHexString(o.hashCode())

答案 4 :(得分:0)

您可能会觉得这很有用 - 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;
}