UTF-8中的字符串构造函数是否已损坏?

时间:2015-05-21 23:10:38

标签: java android utf-8

我有以下代码从缓冲区加载空终止的多字节字符串。它名义上将数据解释为UTF-8,但如果转换失败,则将数据解释为ISO-8859-1。这是代码:

@Override
   public String format(String date_format, boolean use_locale, int precision)
   {
      String rtn = null;
      int len = 0;
      for(int i = 0; i < max_len; ++i)
      {
         if(storage[storage_offset + i] != 0)
            ++len;
         else
            break;
      }
      try
      {
         rtn = new String(storage, storage_offset, len, "UTF-8");
      }
      catch(UnsupportedEncodingException e1)
      {
         try
         {
            rtn = new String(storage, storage_offset, len, "ISO-8859-1");
         }
         catch(UnsupportedEncodingException e2)
         { }
      }
      return rtn;
   }

我的意图是,如果UTF-8的字符串解码失败,我们可以退回。这取决于抛出的UnsupportedEncodingException。我已经对此代码进行了测试,该代码传递了扩展字符(代码大于128)而没有预期的UTF-8模式。我发现的是没有抛出异常,并且为转换后的字符串显示了未知的字形。我的问题是标准库实现是否有任何变化会导致异常不被抛出?

3 个答案:

答案 0 :(得分:2)

如果字符集本身不受支持(即,您指定了字符集且系统无法识别名称),则会引发UnsupportedEncodingException - 如果字节不能正确编码则不会。请注意,采用java.nio.charset.Charset的相应构造函数会抛出该异常(因为没有名称要映射到Charset,因此不可能映射不在那里。

String(byte[], int, int, String)的文档指定行为(即,它未指定:) :)并建议修复:

  

未指定给定字节在给定字符集中无效时此构造方法的行为。当需要更多地控制解码过程时,应该使用CharsetDecoder类。

答案 1 :(得分:2)

根据that String constructor的文档,仅当指定的charsetName未知时才会抛出UnsupportedEncodingException。

  

未指定给定字节在给定字符集中无效时此构造方法的行为。当需要更多地控制解码过程时,应该使用CharsetDecoder类。

答案 2 :(得分:0)

您可以测试字符集是否可用 要获得可用的字符集,请使用:

SortedMap<String, Charset> availableCharsets = Charset.availableCharsets();
    for (Map.Entry<String, Charset> entrySet : availableCharsets.entrySet()) {
        String key = entrySet.getKey();
        Charset value = entrySet.getValue();
        System.out.println("key: " + key + " value: " + value.name());
    }
    System.out.println("The default Charset is: " + Charset.defaultCharset().name());