我的应用默认编码设置为“UTF-8”(启动时使用 -Dfile.encoding = UTF-8 )。 当我使用字符串类方法“getBytes(String charsetName)”和charset =“ISO-8859-1”时,似乎 StringCoding.encode 最终使用默认字符集(UTF-8)而不是给定的(ISO-8859-1)。
由于未知原因,我可以逐步调试此方法,但我无法检查内部元素值(只有名为arg0,arg1 ...的参数)
在java 1.6.10中,编写了StringCoding.encode:
static byte[] encode(String charsetName, char[] ca, int off, int len)
throws UnsupportedEncodingException
{
StringEncoder se = (StringEncoder)deref(encoder);
String csn = (charsetName == null) ? "ISO-8859-1" : charsetName;
if ((se == null) || !(csn.equals(se.requestedCharsetName())
|| csn.equals(se.charsetName()))) {
se = null;
try {
Charset cs = lookupCharset(csn);
if (cs != null)
se = new StringEncoder(cs, csn);
} catch (IllegalCharsetNameException x) {}
if (se == null)
throw new UnsupportedEncodingException (csn);
set(encoder, se);
}
return se.encode(ca, off, len);
}
通过逐步调试,我从不输入if块,然后没有创建带有ISO-8859-1字符集的新StringEncoder。最后,调用Charset.defaultCharset()方法。
任何线索? 谢谢
答案 0 :(得分:3)
如果您没有进入if
块,那么此表达式必须为false
(se == null) || !(csn.equals(se.requestedCharsetName())
|| csn.equals(se.charsetName()))
这意味着:
se
不得为null true
之前,第二部分必须是!
,因此其中一个子表达式必须为真:
csn.equals(se.requestedCharsetName())
csn.equals(se.charsetName())
换句话说,se
已经适合您所请求的字符集名称。
这不是使用VM的“默认”编码;它使用的是此线程中最后使用的编码器。
我高度怀疑你发现了一个JRE错误 - 它看起来对我好。那么是什么导致你开始调试这个?你能提供一个简短但完整的程序来演示错误吗?编码到错误字节的东西?
答案 1 :(得分:0)
您需要更改
-Dfile.ecoding=UTF-8
到
-Dfile.encoding=UTF-8
答案 2 :(得分:0)
encode应该永远不会忽略给定的字符集以恢复到-Dfile.encoding中给出的字符集。
确实如此。正如解码一样,即使源确实显示它找到了charset,并将其设置在行中:
set(encoder, se);
编码或解码都不是线程安全的,因此该值必须被系统默认值覆盖,它可能在解码之前或之后设法使用设置值。
Imho,这是JRE中的一个错误。确实OP有一个拼写错误,但这并没有改变这样一个事实:如果你要求String将一个字节数组解码为UTF-8,它应该总是返回UTF-8,而不是默默地回归到其他东西。