【问题标题】:Can a empty java string be created from non-empty UTF-8 byte array?可以从非空的 UTF-8 字节数组创建一个空的 java 字符串吗?
【发布时间】:2010-10-24 12:54:31
【问题描述】:

我正在尝试调试一些东西,我想知道下面的代码是否可以返回 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 字节序列的第一个字节,但它仍然会产生一个字符串。

为了澄清,这发生在 PowerPC 芯片上,Java 1.4 代码通过 GCJ 编译为本机二进制可执行文件。这基本上意味着大多数赌注都是关闭的。我主要想知道 Java 的“正常”行为,或者 Java 的规范是否做出了任何承诺。

【问题讨论】:

    标签: java string utf-8


    【解决方案1】:

    根据 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

    【讨论】:

      【解决方案2】:

      可能。

      来自 Java 5 API 文档“当给定字节在给定字符集中无效时,此构造函数的行为未指定。”

      我猜这取决于: 您使用的是哪个版本的 java 哪个供应商编写了您的 JVM(Sun、HP、IBM、开源的等)

      一旦文档说“未指定”,所有的赌注都会被取消

      编辑:被Trey打败 听取他关于使用 CharsetDecoder 的建议

      【讨论】:

        【解决方案3】:

        如果Java正确处理BOM mark(我不确定他们是否已经修复它),那么应该可以输入一个只包含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;
        }
        

        【讨论】:

        • 不幸的是,Java 不能正确处理 UTF-8 BOM。根本不处理它,真的;只是将其视为内容的一部分
        【解决方案4】:

        UTF-8 是一种可变长度编码方案,大多数“普通”字符都是单字节的。所以任何给定的非空字节[] 总是会转换成一个字符串,我想。

        如果你想玩它,写一个单元测试,它迭代每个可能的字节值,传入该值的单值数组,并断言字符串是非空的。

        【讨论】:

          猜你喜欢
          • 2020-09-15
          • 1970-01-01
          • 2014-07-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-03-12
          • 1970-01-01
          • 2013-11-29
          相关资源
          最近更新 更多