Java中的打印数组
我正在写一个方法,它可以打印它传递的每个对象。这可以通过调用对象的Java中的打印数组,java,arrays,casting,tostring,Java,Arrays,Casting,Tostring,我正在写一个方法,它可以打印它传递的每个对象。这可以通过调用对象的Object.toString()方法来实现,但不适用于数组。我可以找出它是否是一个带有Object.getClass().isArray()方法的数组,但我不知道如何强制转换它 int[] a; Integer[] b; Object aObject = a; Object bObject = b; // this wouldn't work System.out.println(Arrays.toString(aObjec
Object.toString()
方法来实现,但不适用于数组。我可以找出它是否是一个带有Object.getClass().isArray()
方法的数组,但我不知道如何强制转换它
int[] a;
Integer[] b;
Object aObject = a;
Object bObject = b;
// this wouldn't work
System.out.println(Arrays.toString(aObject));
System.out.println(Arrays.toString(bObject));
如果您想知道如何在任何数组上以编程方式调用此方法,那么使用基元数组是不可能的。查看该类的文档,您将看到每个基元数组类型都有一个重载
toString()
这是因为int[]
例如扩展了Object
而不是Object[]
编辑:这里有一个令人遗憾的冗长解决方案,包括基本数组:
public static void printObject(Object obj) {
String output;
if (obj == null) {
output = "null";
}
else if (obj.getClass().isArray()) {
if (obj instanceof Object[]) {
output = Arrays.toString((Object[])obj); //Object[] overload
}
else if (obj instanceof int[]) {
output = Arrays.toString((int[])obj); //int[] overload
}
//and so on for every primitive type
}
else {
output = obj.toString();
}
System.out.println(output);
}
我希望其他人能提供一个更优雅的解决方案,但基于基本数组的局限性,这可能是最好的解决方案。如果您不知道对象的类型,您可以将对象强制转换为
对象[]
,然后像这样打印(在确保它确实是一个数组并且可以强制转换为对象[]
)。如果它不是对象[]
的实例,则首先使用反射创建对象[]
,然后打印:
private void printAnyArray(Object aObject) {
if (aObject.getClass().isArray()) {
if (aObject instanceof Object[]) // can we cast to Object[]
System.out.println(Arrays.toString((Object[]) aObject));
else { // we can't cast to Object[] - case of primitive arrays
int length = Array.getLength(aObject);
Object[] objArr = new Object[length];
for (int i=0; i<length; i++)
objArr[i] = Array.get(aObject, i);
System.out.println(Arrays.toString(objArr));
}
}
}
输出:
printAnyArray(new int[]{1, 4, 9, 16, 25});
printAnyArray(new String[]{"foo", "bar", "baz"});
[1, 4, 9, 16, 25]
[foo, bar, baz]
如果您只想将其打印为字符串,为什么要将其强制转换?只需将其视为一个对象数组,遍历该数组,并对每个对象调用toString()方法。为什么不让它来解决您的问题?只需编写两个(或多个)名称相同但签名不同的方法,然后让编译器决定在程序执行时调用哪个方法:
void print(Object object) {
System.out.println("Object: " + object);
}
void print(Object[] array) {
System.out.println("Object[]: " Arrays.toString(array));
}
void print(int[] array) {
System.out.println("int[]: " Arrays.toString(array));
}
代码中其他地方的用法示例:
String first = "test";
print(first); // prints "Object: test";
String[] second = {"A", "B"};
print(second); // prints "Object[]: [A, B]"
int[] third = {1, 2};
print(third); // prints "int[]: [1, 2]"
如果您不想依赖对象的类本身来重载Object toString方法(以获得比打印类名和哈希代码更有用的东西),则需要使用反射来获得对象的深层结构 我的建议是使用一个使用反射的库来获得更深层次的结构,例如GSON: 这样可以轻松打印数组,包括多维数组和基本数组
但真正的好处是它以统一的方式打印任何类的对象,不管该类是否以任何有用的方式重写了toString。我如何才能确定它是否是一个基本数组?我还需要知道数组的基元类型。请检查更新的代码,它现在将打印任何数组对象,而不需要您在一个丑陋的
if/elseif/else
有趣的更新链中强制转换到每个基元类型,尽管反射和自动装箱的额外费用值得一提。@PaulBellora我读过大量告诫不要使用所谓“昂贵”反射的文章,但我也看到几乎所有现代框架都很好地利用了它。请阅读以下内容,例如:我的2美分:确保您有一个使用反射的好用例,并且我知道这个问题是否适合于此。非常好,这正是我所需要的。但是如果对象数组包含基元类型,我无法将其强制转换为该数组。
public static String print(Object object) {
return new Gson().toJson(object);
}
public static void test() {
System.out.println(print(new int[][] {new int[] {1, 2, 3} }));
// outputs: [[1,2,3]]
System.out.println(print(new String[] { "aa", "bb", "cc" }));
// outputs: ["aa","bb","cc"]
}