字符串的内部表示?

字符串在java中统一用unicode表示( 即utf-16 LE) ,

对于 String s = "你好哦!";

如果源码文件是GBK编码, 操作系统(windows)默认的环境编码为GBK,那么编译时,  JVM将 按照GBK编码将字节数组解析成字符,然后将字符转换为unicode格式的字节数组,作为内部存储。

当打印这个字符串时,JVM 根据操作系统本地的语言环境,将unicode转换为GBK,然后操作系统将GBK格式的内容显示出来。

当源码文件是UTF-8, 我们需要通知编译器源码的格式,javac -encoding utf-8 ... , 编译时,JVM按照utf-8 解析成字符,然后转换为unicode格式的字节数组, 那么不论源码文件是什么格式,同样的字符串,最后得到的unicode字节数组是完全一致的,显示的时候,也是转成GBK来显示(跟OS环境有关)

乱码如何产生?本质上都是由于 字符串原本的编码格式 与 读取时解析用的编码格式不一致导致的。

例如:

String s = "你好哦!";

System.out.println( new String(s.getBytes(),"UTF-8")); //错误,因为getBytes()默认使用GBK编码, 而解析时使用UTF-8编码,肯定出错。

其中 getBytes() 是将unicode 转换为操作系统默认的格式的字节数组,即"你好哦"的 GBK格式,

new String (bytes, Charset) 中的charset 是指定读取 bytes 的方式,这里指定为UTF-8,即把bytes的内容当做UTF-8 格式对待。

如下两种方式都会有正确的结果,因为他们的源内容编码和解析用的编码是一致的。

System.out.println( new String(s.getBytes(),"GBK"));

System.out.println( new String(s.getBytes("UTF-8"),"UTF-8"));

那么,如何利用getBytes 和 new String() 来进行编码转换呢?网上流传着一种错误的方法:

GBK--> UTF-8:    new String( s.getBytes("GBK") , "UTF-8);   ,这种方式是完全错误的,因为getBytes 的编码与  UTF-8 不一致,肯定是乱码。

但是为什么在tomcat 下,使用 new String(s.getBytes("iso-8859-1") ,"GBK") 却可以用呢? 答案是:

tomcat 默认使用iso-8859-1编码, 也就是说,如果原本字符串是GBK的,tomcat传输过程中,将GBK转成iso-8859-1了,

默认情况下,使用iso-8859-1读取中文肯定是有问题的,那么我们需要将iso-8859-1 再转成GBK, 而iso-8859-1 是单字节编码的,

即他认为一个字节是一个字符, 那么这种转换不会对原来的字节数组做任何改变,因为字节数组本来就是由单个字节组成的,

如果之前用GBK编码,那么转成iso-8859-1后编码内容完全没变, 则 s.getBytes("iso-8859-1")  实际上还是原来GBK的编码内容

则 new String(s.getBytes("iso-8859-1") ,"GBK")  就可以正确解码了。 所以说这是一种巧合。

如何正确的将GBK转UTF-8 ? (实际上是unicode转UTF-8)

String gbkStr = "你好哦!"; //源码文件是GBK格式,或者这个字符串是从GBK文件中读取出来的, 转换为string 变成unicode格式

//利用getBytes将unicode字符串转成UTF-8格式的字节数组

byte[] utf8Bytes = gbkStr.getBytes("UTF-8");

//然后用utf-8 对这个字节数组解码成新的字符串

String utf8Str = new String(utf8Bytes, "UTF-8");

简化后就是:

unicodeToUtf8 (String s) {

return new String( s.getBytes("utf-8") , "utf-8");

}

UTF-8 转GBK原理也是一样

return new String( s.getBytes("GBK") , "GBK");

其实核心工作都由  getBytes(charset) 做了。

getBytes 的JDK 描述:Encodes this String into a sequence of bytes using the named charset, storing the result into a new byte array.

另外对于读写文件,

OutputStreamWriter w1 = new OutputStreamWriter(new FileOutputStream("D:\\file1.txt"),"UTF-8");

InputStreamReader( stream, charset)

可以帮助我们轻松的按照指定编码读写文件。

转自:

unix系统编码 java_Java 正确的做字符串编码转换相关推荐

  1. 硬编码 java_Java编程中的硬编码问题

    在计算机程序或文本编辑中,硬编码是指将可变变量用一个固定值来代替的方法. 用这种方法编译后,如果以后需要更改此变量就非常困难了. 大部分程序语言里,可以将一个固定数值定义为一个标记,然后用这个特殊标记 ...

  2. JAVA学习 API_day03(字符串编码, 泛型, 数据结构, Collection)

    字符串编码, 泛型, 数据结构, Collection 1.字符串编码 2.泛型 3.数据结构 4.Collection 1.字符串编码 1.String -> 字符序列 (中文\英文) JVM ...

  3. unix系统编码 java_JAVA字符编码系列三:Java应用中的编码问题

    这两天抽时间又总结/整理了一下各种编码的实际编码方式,和在Java应用中的使用情况,在这里记录下来以便日后参考. 为了构成一个完整的对文字编码的认识和深入把握,以便处理在Java开发过程中遇到的各种问 ...

  4. itpt_TCPL 第五章:指针和数组 - 第八章:UNIX系统接口

    2016.10.11 - 01.09 个人英文阅读练习笔记(极低水准). 10.11 第五章:指针和数组 指针是保存一个变量的地址的变量.指针在C中被大量使用,部分是因为有时候它是唯一表达计算的方法, ...

  5. python字符串编码及乱码解决方案

    http://blog.csdn.net/pipisorry/article/details/44136297 字符编码详解 [字符编码ASCII,Unicode和UTF-8] 主要非英文字符集的编码 ...

  6. Unix系统 - 进程管理

    写在前面:注意,本章除了讲解进程管理,还包含网络编程Socket API的知识. 这里写目录标题 一.进程 1.1基础知识 1.1.1进程ID 1.1.2查看进程 1.1.2 父子进程概念 1.1.3 ...

  7. Unix及类Unix系统文本编辑器的介绍

    概述 Vim是一个类似于Vi的著名的功能强大.高度可定制的文本编辑器,在Vi的基础上改进和增加了很多特性.VIM是纯粹的自由软件. Vim普遍被推崇为类Vi编辑器中最好的一个,事实上真正的劲敌来自Em ...

  8. python中文字符串编码_浅谈python下含中文字符串正则表达式的编码问题

    前言 Python文件默认的编码格式是ascii ,无法识别汉字,因为ascii码中没有中文. 所以py文件中要写中文字符时,一般在开头加 # -*- coding: utf-8 -*- 或者 #co ...

  9. java中文字符怎么保证出现正确_JAVA中文字符编码问题详解

    JAVA中文字符编码问题详解 JAVA的中文字符乱码问题一直很让人头疼.特别是在WEB应用中.网上的分析文章和解决方案都很多,但总是针对某些特定情况的.很多次遇到乱码问题后,经过极为辛苦的调试和搜索资 ...

最新文章

  1. node简单实现excel文件下载
  2. JavaScript实现 按钮不可过频繁使用
  3. (开发)ESLint - 代码规范
  4. transfer function
  5. python requests post 中文乱码问题
  6. NSkyKit 项目实践-Dagger2
  7. 多线程 并发编程 看了这篇 终于了解了
  8. .bat文件该图标_电脑桌面图标变成白色方块图标怎么办?
  9. 苹果推送iOS 15.0.1版本 修复涉及iPhone 13的Bug
  10. SecureCRT 连接oracle数据库xServer图形界面服务
  11. el表达式原样输出问题
  12. 开源中国开源世界高峰论坛
  13. 微分方程数值解法(2)——椭圆型方程的有限差分法
  14. 最高响应比调度算法_高响应比调度算法(c语言程序实现)
  15. C#使用ITextSharp操作pdf
  16. Hexo添加可控制网易云音乐播放器
  17. 【lssvm分类】基于粒子群算法优化最小二乘支持向量机lssvm实现数据分类matlab代码
  18. 无线安全之破解WPA/WPA2 加密WiFi
  19. Nginx配置双重用户认证
  20. 读取Excel工具类ExcelUtils

热门文章

  1. 一行代码取出HTML页面某个按钮的css属性,比如margin
  2. 如何在postman里为类型为Edm.DateTime的OData参数指定正确格式的值
  3. 如何在Android Studio里关掉instant run
  4. how is SAP ui5 formatter resolved
  5. Design layer interface的设计与实现
  6. 如何判断Marketing Cloud里OData服务调用成功了
  7. Java Thread pool的学习笔记
  8. responsibility和workload的区别
  9. SAP CRM Product UI是如何判断当前会话发生了数据写操作的
  10. 如何处理VMware启动虚拟机时的错误信息Failed to lock the file