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. 自动部署基于Maven的war文件到远程Tomcat

    转载自:https://www.cnblogs.com/jtlgb/p/7018705.html Tomcat 7发布URL = http://localhost:8080/manager/text命 ...

  2. bzoj 1898 [Zjoi2005]Swamp 沼泽鳄鱼——矩阵快速幂

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1898 当然是邻接矩阵做转移矩阵来快速幂. 对于鳄鱼,好在它们周期的lcm是12,也就是每12 ...

  3. Laravel 传递数据到视图

    // 使用传统的方法 $view = view('greeting')->with('name', 'Victoria'); // 使用魔术方法 $view = view('greeting') ...

  4. HDU4006(小根堆)

    The kth great number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Oth ...

  5. 【转】 Pro Android学习笔记(八九):了解Handler(3):延迟执行小例子

    目录(?)[-] 小例子 Handler的处理 Activity的代码片段 后台线程和UI的互动 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://b ...

  6. Java-API:un-java.text.DecimalFormat

    ylbtech-Java-API:java.text.DecimalFormat 1.返回顶部   2.返回顶部   3.返回顶部   4.返回顶部   5.返回顶部 0. https://docs. ...

  7. AWS + Stunnel + Squid ***

    [需求] 第一,能***. 第二,在企业网络要能突破端口限制. [原理] 利用AWS提供的一年免费EC2服务,搭建一台自己的VPS,在VPS中利用Stunnel与本机建立加密连接,将本地http请求通 ...

  8. cpu上下文切换(下)

    --怎么查看系统的上下文切换情况 过多的上下文切换,会把cpu时间消耗在寄存器.内核栈以及虚拟内存等数据的保存和恢复上,缩短进程真正运行的时间,成了系统性能大幅下降的一个元凶. 查看,使用vmstat ...

  9. 【转】ruby中nil?, empty? and blank?的选择

    In Ruby, you check with nil? if an object is nil:article = nil article.nil? # => true empty? chec ...

  10. c++ 端口扫描程序

    第一.原理 端口扫描的原理很简单,就是建立socket通信,切换不通端口,通过connect函数,如果成功则代表端口开发者,否则端口关闭. 所有需要多socket程序熟悉,本内容是在window环境下 ...