ucenter的中文问题终于解决,这也暴露我对Java编码知识的严重不足,经过多次试验和搜索,对这块知识终于有了一个新的认识,所以把理解的内容写道这里

1:JVM的内存中字符串的编码格式是统一的吗?

JVM里面的任何字符串资源都是Unicode,String相当于 char[] 。 而JVM中的byte[]是带编码的,比如,Big5,GBK,GB2312,UTF-8之类的。一个GBK编码的byte[] 转换成 String,

其实就是从GBK编码向Unicode编码转换。一个String转换成一个Big5编码的byte[],其实就是从Unicode编码向Big5编码转换。所以,Unicode是所有编码转换的中间介质。所有的编码都有一个转换器可以转换到Unicode,而Unicode也可以转换到其他所有的编码。

这个做个测试

public class CodeTest {

    @Test
public void test() throws UnsupportedEncodingException {
String str="I am 高兴";
System.out.println(str);
}
}

在debug中显示'高'的值我39640,为该中文字符的unicode的编码,Java中的char是2个字节的。

2:源文件的编码对编译的影响。

这里我专门使用了Javac和Java两个命令来做个这个试验,源码如下:

public class CodeTest
{
public static void main (String[] args)
{
String str="高兴";
System.out.println(str);
}
}

这个源码我在UE里面把他转成GBK的,编译没有问题。但是转成UTF-8格式,就出现了问题:”楂樺叴“ ,

public class CodeTest {

    @Test
public void test() throws UnsupportedEncodingException {
// String str="I am 君山";
// System.out.println(str);
String str="高兴";
str=new String(str.getBytes("UTF-8"),"GBK");
System.out.println(str);
}
}

str的值为”楂樺叴“。说明源文件的编码对编译时有影响的。GBK为本地系统的编码。Javac在编译过程中把UTF-8的转成了GBK.  下面一段是解释:

Java编译器在对源文件编译前,首先会源文件转换为unicode编码,然后再进行编译。例如:我们的源文件是以UTF-8的方式保存的,而在编译时编译器却把它当作是用GBK方式保存的,这样编译器就会按照GBK->Unicode的编码转换方法对源文件进行转换,然后再编译,这样当然会出错,实际上编译器应当按照UTF-8->Unicode的编码转换方法来对源文件进行转换。

常我们手动建立一个java文件Demo.java,并保存。此时Demo.java文件的编码为ANSI,中文操作系统下就是GBK.然后使用javac命令来编译该源文件。”javac Demo.java”。Javac也需要读取java文件,那么javac是使用什么编码来解码我们读取的字节呢?其实javac采用了操作系统默认的GBK编码解码我们读取的字节,这个编码正好也是Demo.java文件的编码,二者一致,所以不会出现乱码情况。让我们来做点手脚,在保存Demo.java文件时,我们选择UTF-8保存。此时Demo.java文件编码就是UTF-8了。我们再使用”javac Demo.java”来编译,如果Demo.java里含有中文字符,此时控制台会出现警告信息,也出现了乱码。究其原因,就是因为javac采用了GBK编码解码我们读取的字节。因为我们的字节是UTF-8编码的,所以会出现乱码。如果不信的话你可以自己试试。那么解决办法呢?解决办法就是使用javac的encoding参数来制定我们的解码编码。如下:javac -encoding UTF-8 Demo.java。这里我们指定了使用UTF-8来解码读取的字节,由于这个编码和Demo.java文件编码一致,所以不会出现乱码情况了。

3:String的编码和解码

String对象的getBytes()可以对字符串进行编码转化成byte数组。

 public static void encode() {
String name = "I am 君山";
toHex(name.toCharArray());
try {
byte[] iso8859 = name.getBytes("ISO-8859-1");
toHex(iso8859);
byte[] gb2312 = name.getBytes("GB2312");
toHex(gb2312);
byte[] gbk = name.getBytes("GBK");
toHex(gbk);
byte[] utf16 = name.getBytes("UTF-16");
toHex(utf16);
byte[] utf8 = name.getBytes("UTF-8");
toHex(utf8);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}

默认使用系统编码。

String(byte[],charset)这是对字节数组进行解码。这个是经常容易出问题的地方,你使用gbk编码,却使用utf-8解码,那么生成的String的unicode的编码已经变了。字节数组通过编码映射到指定的字符,然后这些字符转成unicode编码转成

解码的黑洞问题:

将中文和中文符号经过不支持中文的 ISO-8859-1 编码后,所有字符变成了“?”,这是因为用 ISO-8859-1 进行编解码时遇到不在码值范围内的字符时统一用 3f 表示,这也就是通常所说的“黑洞”,所有 ISO-8859-1 不认识的字符都变成了“?”。

java的编码问题详解的更多相关文章

  1. Java:编码的详解

    ASCII:美国信息标准信息码,用一个字节的7为表示. ISO8859-1:拉丁码表 欧洲码表 ,用一个字节的8位表示. GB2312:中国的中文编码表. GBK:中国的中文编码表升级,融合了更多的中 ...

  2. Java版人脸检测详解下篇:编码

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  3. 国际化,java.util.ResourceBundle使用详解

    java.util.ResourceBundle使用详解   一.认识国际化资源文件   这个类提供软件国际化的捷径.通过此类,可以使您所编写的程序可以:          轻松地本地化或翻译成不同的 ...

  4. java.util.ResourceBundle使用详解

    java.util.ResourceBundle使用详解   一.认识国际化资源文件   这个类提供软件国际化的捷径.通过此类,可以使您所编写的程序可以:          轻松地本地化或翻译成不同的 ...

  5. java.util.ResourceBundle使用详解(转)

    java.util.ResourceBundle使用详解   一.认识国际化资源文件   这个类提供软件国际化的捷径.通过此类,可以使您所编写的程序可以:          轻松地本地化或翻译成不同的 ...

  6. java web.xml配置详解(转)

    源出处:java web.xml配置详解 1.常规配置:每一个站的WEB-INF下都有一个web.xml的设定文件,它提供了我们站台的配置设定. web.xml定义: .站台的名称和说明 .针对环境参 ...

  7. 【转】Eclipse Java注释模板设置详解

    Eclipse Java注释模板设置详解   设置注释模板的入口: Window->Preference->Java->Code Style->Code Template 然后 ...

  8. java ssl https 连接详解 生成证书 tomcat keystone

    java ssl https 连接详解 生成证书 我们先来了解一下什么理HTTPS 1. HTTPS概念 1)简介 HTTPS(全称:Hypertext Transfer Protocol over ...

  9. Java并发关键字Volatile 详解

    Java并发关键字Volatile 详解 问题引出: 1.Volatile是什么? 2.Volatile有哪些特性? 3.Volatile每个特性的底层实现原理是什么? 相关内容补充: 缓存一致性协议 ...

随机推荐

  1. php是如何工作的

    a:前提条件: apache服务器启动正常工作 b:客户端浏览器在地址栏输入一个程序地栏 按回车发送请求 {请求}http://127.0.0.1/day03/1.php c:apache接收请求,并 ...

  2. 浅学soap--------2

    使用wsdl文件: 生成wsdl <?php require('person.class.php'); // 引入生成wsdl的类文件 require('SoapDiscovery.class. ...

  3. MFC获得当前应用程序目录的GetCurrentDirectory()和GetModuleFileName()函数

    在 开发过程中经常需要获得程序当前的运行目录,这时就可以使用GetCurrentDirectory()和GetModuleFileName()函 数,GetCurrentDirectory只是返回当前 ...

  4. python之ConfigParser的使用。

    一.ConfigParser简介 ConfigParser 是用来读取配置文件的包.配置文件的格式如下:中括号“[ ]”内包含的为section.section 下面为类似于key-value 的配置 ...

  5. 聊聊WPF中字体的设置

    1. 今天帮同事调试一个字体的bug:TextBox中的中文显示大小不一致, 比如包含"杰","热". 原因是WPF针对点阵字体需要指定特定字体才能正确渲染, ...

  6. canvas渐变

    代码: 1 /** 2 * Created by Administrator on 2016/1/29. 3 */ 4 function draw(id){ 5 var canvas = docume ...

  7. 运行jar应用程序引用其他jar包的三种常用方法(jar命令)

    参考:http://blog.csdn.net/wangmuming/article/details/44343017 方法一.使用Extension Classloader来加载 你可以把需要加载的 ...

  8. QQ控件时光轴特效总结

    1.插入HTML数据 插入html代码,一般的做法是通过document.getElementById("").innerHTML来实现. 然而在该控件中,它通过JS replac ...

  9. 侯捷STL学习(二)--序列容器测试

    第六节:容器之分类和各种测试(四) stack不提供iterator操作,破坏了容器的独特性,先进先出. 使用容器multiset(允许元素重复) 内部是红黑树,insert操作就保证了排好了序. 标 ...

  10. svn使用技巧一:更新、提交、资源库同步之间区别

    提交:是用本地文件覆盖服务器的文件,只有提交会导致服务器上发生变化 更新:只是把服务器上最新版本下载到客户端,规则如下: 1.如果你本地的某个文件没有修改过,而服务器上的这个文件别人已经提交过新版本, ...