让我说我很懒。
而不是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);
}
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?
谢谢你的帮助:)。
答案 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
,即打印对象的类和引用的哈希值。
修改强>
答案 1 :(得分:1)
你有
public static void println(Object ... o) {
和
public static void println(int ... o) {
这些方法的适用于int[]
参数。对于第一个,整个数组将被视为单个对象并作为单个参数传递。对于第二个,数组内容将被视为变量参数本身。
假设你有int[] v = {a,b,c}
。第一种方法可以称为println(v)
(因为v
是Object
),但第二种方法也可以被称为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;
}