我正在尝试创建一个几乎将任何内容都作为参数的方法,并使用一些定界符返回该值的串联字符串表示形式。
public static String getConcatenated(char delim, Object ...names) {
String[] stringArray = Arrays.copyOf(names, names.length, String[].class); //Exception here
return getConcatenated(delim, stringArray);
}
和实际的方法
public static String getConcatenated(char delim, String ... names) {
if(names == null || names.length == 0)
return "";
StringBuilder sb = new StringBuilder();
for(int i = 0; i < names.length; i++) {
String n = names[i];
if(n != null) {
sb.append(n.trim());
sb.append(delim);
}
}
//Remove the last delim
return sb.substring(0, sb.length()-1).toString();
}
我有以下JUnit测试:
final String two = RedpillLinproUtils.getConcatenated(' ', "Shervin", "Asgari");
Assert.assertEquals("Result", "Shervin Asgari", two); //OK
final String three = RedpillLinproUtils.getConcatenated(';', "Shervin", "Asgari");
Assert.assertEquals("Result", "Shervin;Asgari", three); //OK
final String four = RedpillLinproUtils.getConcatenated(';', "Shervin", null, "Asgari", null);
Assert.assertEquals("Result", "Shervin;Asgari", four); //OK
final String five = RedpillLinproUtils.getConcatenated('/', 1, 2, null, 3, 4);
Assert.assertEquals("Result", "1/2/3/4", five); //FAIL
但是,测试在最后一部分失败,但以下情况除外:
java.lang.ArrayStoreException at java.lang.System.arraycopy(Native Method) at java.util.Arrays.copyOf(Arrays.java:2763)
有人可以发现错误吗?
最佳答案
原因
您不能将Integer
放在String[]
中。这就是为什么您得到ArrayStoreException
的原因。 Arrays.copyOf
不进行转换。
从the API:T[] copyOf(U[] original, int newLength, Class< ? extends T[]> newType)
抛出:ArrayStoreException
-如果从original
复制的元素不是可以存储在类newType
的数组中的运行时类型。ArrayStoreException
API有一个示例:
抛出该异常表示试图将错误类型的对象存储到对象数组中。例如,以下代码生成一个ArrayStoreException
:
Object x[] = new String[3];
x[0] = new Integer(0);
也可以看看
JLS 10.10 Array Store Exception
解决方法
也就是说,您实际上不需要
String...
和Arrays.copyOf
到String[]
。您的getConcatenated
可以使用Object...
,就可以了。public static String getConcatenated(char delim, Object... objs) {
if(objs == null || objs.length == 0)
return "";
StringBuilder sb = new StringBuilder();
for (Object o : objs) {
if(o != null) {
if (sb.length() > 0) sb.append(delim);
sb.append(o.toString().trim());
}
}
return sb.toString();
}
现在,您可以执行以下操作:
System.out.println(getConcatenated(';', "Shervin", null, "Asgari", null));
// prints "Shervin;Asgari"
System.out.println(getConcatenated('/', 1, 2, null, 3, 4));
// prints "1/2/3/4"
System.out.println(getConcatenated(':', " ", null, "boo", "boo"));
// prints "boo:boo"
请注意,这遵循原始代码中的预期规范,即
trim()
并跳过null
。