java 查看字符集_如何在Java中查找默认的字符集/编码?

小编典典

这真的很奇怪。。。一旦设置,默认的Charset将被缓存,并且当类在内存中时不会更改。将"file.encoding"属性设置为System.setProperty("file.encoding", "Latin-1");无。每次Charset.defaultCharset()调用时,它都会返回缓存的字符集。

这是我的结果:

Default Charset=ISO-8859-1

file.encoding=Latin-1

Default Charset=ISO-8859-1

Default Charset in Use=ISO8859_1

我正在使用JVM 1.6。

(更新)

好。我确实使用JVM 1.5重现了你的错误。

查看源代码1.5,未设置缓存的默认字符集。我不知道这是否是一个错误,但是1.6更改了此实现并使用了缓存的字符集:

JVM 1.5:

public static Charset defaultCharset() {

synchronized (Charset.class) {

if (defaultCharset == null) {

java.security.PrivilegedAction pa =

new GetPropertyAction("file.encoding");

String csn = (String) AccessController.doPrivileged(pa);

Charset cs = lookup(csn);

if (cs != null)

return cs;

return forName("UTF-8");

}

return defaultCharset;

}

}

JVM 1.6:

public static Charset defaultCharset() {

if (defaultCharset == null) {

synchronized (Charset.class) {

java.security.PrivilegedAction pa =

new GetPropertyAction("file.encoding");

String csn = (String) AccessController.doPrivileged(pa);

Charset cs = lookup(csn);

if (cs != null)

defaultCharset = cs;

else

defaultCharset = forName("UTF-8");

}

}

return defaultCharset;

}

当你将文件编码设置file.encoding=Latin-1为下次调用时Charset.defaultCharset(),会发生这种情况,因为未设置缓存的默认字符集,它将尝试为name查找合适的字符集Latin-1。找不到此名称,因为它不正确,并返回default UTF-8。

至于诸如此类的IO类为何OutputStreamWriter返回意外结果的原因,对于JVM 1.5和JVM 1.6

,sun.nio.cs.StreamEncoder(这些IO类使用巫婆的)实现也有所不同。Charset.defaultCharset()如果未为IO类提供默认编码,则JVM 1.6实现基于该方法来获取默认编码。JVM 1.5实现使用另一种方法Converters.getDefaultEncodingName();来获取默认字符集。此方法使用自己的默认字符集缓存,该缓存是在JVM初始化时设置的:

JVM 1.6:

public static StreamEncoder forOutputStreamWriter(OutputStream out,

Object lock,

String charsetName)

throws UnsupportedEncodingException

{

String csn = charsetName;

if (csn == null)

csn = Charset.defaultCharset().name();

try {

if (Charset.isSupported(csn))

return new StreamEncoder(out, lock, Charset.forName(csn));

} catch (IllegalCharsetNameException x) { }

throw new UnsupportedEncodingException (csn);

}

JVM 1.5:

public static StreamEncoder forOutputStreamWriter(OutputStream out,

Object lock,

String charsetName)

throws UnsupportedEncodingException

{

String csn = charsetName;

if (csn == null)

csn = Converters.getDefaultEncodingName();

if (!Converters.isCached(Converters.CHAR_TO_BYTE, csn)) {

try {

if (Charset.isSupported(csn))

return new CharsetSE(out, lock, Charset.forName(csn));

} catch (IllegalCharsetNameException x) { }

}

return new ConverterSE(out, lock, csn);

}

但是我同意这些意见。你不应该依赖此属性。这是一个实现细节。

2020-03-10

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值