提问人:Steve Armstrong 提问时间:5/7/2009 最后编辑:Steve Armstrong 更新时间:5/8/2009 访问量:3674
可以从非空的 UTF-8 字节数组创建空的 java 字符串吗?
Can a empty java string be created from non-empty UTF-8 byte array?
问:
我正在尝试调试某些内容,我想知道以下代码是否可以返回 true
public boolean impossible(byte[] myBytes) {
if (myBytes.length == 0)
return false;
String string = new String(myBytes, "UTF-8");
return string.length() == 0;
}
我可以传入一些将返回 true 的值吗?我已经摆弄了只传入 2 字节序列的第一个字节,但它仍然产生一个字符串。
澄清一下,这发生在 Java 1.4 上的 PowerPC 芯片上,该代码通过 GCJ 编译为本机二进制可执行文件。这基本上意味着大多数赌注都关闭了。我主要想知道 Java 的“正常”行为或 Java 的规范是否做出了任何承诺。
答:
UTF-8 是一种可变长度编码方案,大多数“正常”字符是单字节。因此,任何给定的非空 byte[] 将始终转换为字符串,我想。
如果你想玩它说,写一个单元测试,它遍历每个可能的字节值,传入该值的单值数组,并断言字符串是非空的。
根据 java.util.String 的 javadoc,当 bytearray 包含无效或意外数据时,不会指定 new String(byte[], “UTF-8”) 的行为。如果希望生成的字符串具有更高的可预测性,请使用 http://java.sun.com/j2se/1.5.0/docs/api/java/nio/charset/CharsetDecoder.html。
可能。
来自 Java 5 API 文档“当给定字节在给定字符集中无效时,此构造函数的行为是未指定的。
我想这取决于: 您使用的是哪个版本的 java 哪个供应商编写了您的 JVM(Sun、HP、IBM、开源 JVM 等)
一旦文档显示“未指定”,所有赌注都关闭了
编辑:被 Trey 击败 听听他关于使用 CharsetDecoder 的建议
如果 Java 正确处理了 BOM 标记(我不确定他们是否已经修复了它),那么应该可以只输入一个带有 BOM 的字节数组(U+FEFF,在 UTF-8 中是字节序列 EF BB BF)并得到一个空字符串。
更新:
我用 1-3 个字节的所有值测试了该方法。在 Java 1.6 上,它们都没有返回空字符串。以下是我用于不同字节数组长度的测试代码:
public static void main(String[] args) throws UnsupportedEncodingException {
byte[] test = new byte[3];
byte[] end = new byte[test.length];
if (impossible(test)) {
System.out.println(Arrays.toString(test));
}
do {
increment(test, 0);
if (impossible(test)) {
System.out.println(Arrays.toString(test));
}
} while (!Arrays.equals(test, end));
}
private static void increment(byte[] arr, int i) {
arr[i]++;
if (arr[i] == 0 && i + 1 < arr.length) {
increment(arr, i + 1);
}
}
public static boolean impossible(byte[] myBytes) throws UnsupportedEncodingException {
if (myBytes.length == 0) {
return false;
}
String string = new String(myBytes, "UTF-8");
return string.length() == 0;
}
评论