转自:http://singleant.iteye.com/blog/686383
本周遇到一个java乱码问题,于是对java的编码问题做了一些实验和了解。简单分析如下:
先看下如下代码:
Java代码
import java.io.UnsupportedEncodingException;
public class CharSetTest {
public static void main(String[] args) throws UnsupportedEncodingException {
String test = " 篮球 " ;
byte [] defaultResult = test.getBytes();
for ( byte e : defaultResult) {
System. out .print(e + " " );
}
System. out .println(System. getProperty ( "file.encoding" ));
System. out .println( "test=" + test);
}
}
1.执行 javac CharSetTest.java,能正常编译,但是得到如下警告:
CharSetTest.java:5: warning: unmappable character for encoding ASCII
String test = "????";
分析一下为什么会这样呢?对于java编译器来说,CharSetTest.java就是一个文本文件,java编译器要解析这个文本文件并编译生成.class文件。分析了下原因大概是这样的:CharSetTest.java一定是以某一种编码格式来存储的,所以java编译器一定要知道该文本文件时用什么来编码的,如果没有指定就用默认认为文件的编码格式是” ANSI_X3.4-1968”(不同环境可能不一样),所以就会发现无法解释的中文而出现了乱码。
那么以上问题该如何解决,就是要在编译的时候告诉编译器,需要编译的java文件的编码格式,否则编译器有可能遇到不能理解的字符就当做乱码处理了。由于 CharSetTest.java是GBK格式的,所以通过如下命令完成:
Javac CharSetTest.java –encoding=GBK。
2. 通过执行Javac CharSetTest.java –encoding=GBK,已经能得到正确的class文件了,但是执行 java CharSetTest,结果如下:
63 63 ANSI_X3.4-1968
test=??
那么既然已经正确编译了,为什么得到的输出结果还会是乱码呢?前面已经可以肯定.class文件里面存放的中文字符串是正确的了,那原因肯定是在JVM 从.class文件读取这个字符串字节流并构建String对象的时候采用了错误的字符编码来构建字节流。进而导致从JVM输出字符串的字节流到我们控制台的时候,出现乱码。那么很显然,我们必须告诉jvm我们控制台的编码,或者我们希望它采用什么字符编码来构建字节流。如果没有告诉jvm,那么文件的编码格式是” ANSI_X3.4-1968”(不同环境可能不一样)。
假设我们控制台是GBK的编码,那么只要我们正确告诉它,它就能正确的返回字节流了。那么原因就比较简单,我们没有正确告诉JVM我们需要它构造字符串输出流的时候应该采用的编码格式。那么该如何处理呢?通过如下命令:
java -Dfile.encoding=GBK CharSetTest
得到结果:
-64 -70 -57 -14 GBK
test=篮球
以上试验是在linux环境上面做的。在eclipse下面并不会成立,因为eclipse会帮我们做一些判断。同时不同的操作系统环境可能也不一样。
最后总结:
Java的class文件采用UTF-8,在JVM里面采用UTF-16。整个过程中编码转换大概可以看下图:
从上图可以理解不管采用那种格式的源文件,只要正确告诉编译器,编译器就会得到正确的结果。同时只要告诉JVM正确的输出流需要的编码格式,JVM总会返回正确编码格式的输出流。
那么要想不产生乱码要注意两个环节:
1. 告诉编译器你的源文件编码。
2. 告诉jvm你显示或者构造字符串输出流时希望的编码。
尤其JSP乱码时要注意request请求采用的编码和解析request时候采用的编码是否一致,response的编码和html charset的编码是否一致。
同时我们常遇到jsp、数据库等乱码问题可以找一下是否是以下两种原因:
1. 误解型:a文件是GBK编码,但是你以为是UTF-8型编码,所以用UTF-8来理解它,就会出现乱码。
2. 无能为力型:a文件时GBK编码,你也知道它是GBK编码,但是你想转换成ISO-8859-1的方式来显示,但是GBK里面有很多字符时ISO- 8859-1所不能解释的,这时也会出现乱码。
- 大小: 34.9 KB
分享到:
相关推荐
### Java 字符编码详解 #### 一、Java 字符编码基础概念 在深入探讨 Java 字符编码的问题之前,我们先来了解一下字符编码的基本概念。字符编码是计算机内部表示字符的一种方式,它涉及到如何将人类可读的文字转换...
本文将围绕“Java字符集编码简记”这一主题,深入探讨相关知识点,并结合标签“源码”和“工具”,探讨在实际开发中如何运用和处理字符编码问题。 首先,我们需要理解字符集的概念。字符集是一系列符号的集合,例如...
在Java中,字符串的处理是非常常见的操作之一,而字符编码是确保数据正确显示的关键因素。本篇文章将重点介绍Java中字符串编码的转换方法及其在Web环境中的应用。 #### 二、Java中的字符串与字符编码 在Java中,`...
Java中的字符编码转换是编程实践中一个至关重要的概念,尤其是在处理多语言环境和跨平台交互时。Java通过统一采用UTF-16编码格式在JVM内部处理字符,简化了字符操作的复杂性。UTF-16是一种变长的Unicode编码,它可以...
- Java使用Unicode作为内部字符编码,这意味着所有Java字符串都是UTF-16编码的。 - `java.nio.charset` 包提供了许多类和接口,用于字符编码和解码,如`Charset`、`CharsetDecoder`和`CharsetEncoder`。 3. **...
UTF-8(Unicode Transformation Format-8)是一种可变长度的字符编码格式,主要用于在网络中快速传输Unicode字符。UTF-8的基本原理是根据Unicode字符的范围,将其映射成不同长度的编码,具体规则如下: - 每个英文...
例如,如果字节数组是以GBK编码的“中文”,则通过`new String(bytes, "GBK")`可以正确地将其转换为Java内部的Unicode表示。 2. **getBytes(charset)** `getBytes(String charset)` 方法用于将字符串转换为特定...
- Java内部默认使用Unicode编码,但在输入输出、网络传输、文件读写时需注意设置合适的编码,否则可能导致乱码。 - Java中的`InputStreamReader`和`OutputStreamWriter`用于在字节流和字符流之间转换,可以指定...
JAVA作为一种广泛使用的编程语言,尤其注重国际化和多语言支持,因此采用了UNICODE作为其内部字符表示的标准。本文将深入探讨JAVA中字符编码的基本概念、UNICODE的应用方式及其内部实现机制。 #### 二、JAVA中的...
### Java字符编码转换详细过程 #### 一、Java程序的生命周期与字符编码处理流程 Java程序的生命周期可以概括为三个主要阶段:编写源代码、编译源代码以及运行编译后的类文件。在这个过程中,涉及到多种字符编码的...
上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。这被称为ASCII码,一直沿用至今。 ASCII码一共规定了128个字符的编码,比如空格“SPACE”是32(二进制00100000),...
Java字符编码是编程中至关重要的一个概念,尤其是在处理多语言数据时。本文主要探讨了Java中与字符编码相关的基础知识,包括ISO8859-1、GB2312、GBK、Unicode以及UTF编码。 首先,ISO8859-1是一种早期的单字节编码...
文档强调了在Java虚拟机(JVM)内部字符统一采用UTF-16编码格式的重要性,并详细解释了如何实现不同编码格式间的转换。通过本文档的学习,开发者可以更好地理解Java中的字符编码机制,从而避免因编码问题导致的应用...
Java使用Unicode作为其内部字符编码,Unicode是一种包含几乎世界上所有语言字符的广泛字符集。Java中,字符串(String)是以UTF-16编码存储的,这是一种Unicode的变体。在输入输出操作中,如读写文件或网络通信,...
字符编码是将计算机内部二进制数据转换为人类可读的文字的过程。常见的字符编码方式包括ASCII、GBK、UTF-8等。其中,UTF-8由于其良好的兼容性和国际化的支持,在现代Web开发中被广泛采用。 #### 二、字符编码问题...
1. Java内部统一使用UTF-16编码存储字符,简化了内存中的字符处理。 2. Java的IO系统分为面向字节和面向字符两类流,前者保持原始二进制数据不变,后者处理字符编码转换。 3. Reader和Writer默认使用系统默认编码,...
Java内部使用Unicode编码,这意味着在内存中,所有的字符串都是以Unicode编码的形式存在。当读取或写入文件,或与其他系统进行通信时,Java需要进行编码转换,以匹配目标系统的字符编码。例如,如果一个Java程序从...
Java中的`Charset`类提供了处理字符编码的方法。例如,我们可以使用`new String(byte[], charsetName)`构造函数将字节数组转换为字符串,或者使用`String.getBytes(charsetName)`将字符串转换为字节数组。这里的`...