测试文件1:UnicodeTest1.java-----该文件自身编码为utf-8
测试文件2:UnicodeTest2.java-----该文件自身编码为GBK
测试结果:
注意:可以看到在两个java文件代码完全一样情况下,产生的结果却有差别。
package com.java.unicode;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.util.Arrays;
/**
* 本java文件编码为UTF-8
* */
public class UnicodeTest1 {
public static void main(String[] args) throws Exception{
String GBK_fileName = "E:\\workspace\\TestProgram\\src\\com\\java\\unicode\\GBK.txt";
String UTF_8_fileName = "E:\\workspace\\TestProgram\\src\\com\\java\\unicode\\UTF-8.txt";
String str = "你是傻逼啊啊啊啊啊啊啊哈哈哈";
System.out.println(codeString(GBK_fileName));
FileInputStream g_fis = new FileInputStream(GBK_fileName);
byte[] g_bytes = new byte[50];
int g_len = g_fis.read(g_bytes);
System.out.println(codeString(UTF_8_fileName));
FileInputStream u_fis = new FileInputStream(UTF_8_fileName);
byte[] u_bytes = new byte[50];
int u_len = u_fis.read(u_bytes);
byte[] j_bytes_G = str.getBytes("GBK");
byte[] j_bytes_U = str.getBytes("utf-8");
//str.getBytes()默认编码方式为当前java文件的编码方式,非系统默认编码
byte[] j_bytes_F = str.getBytes();
j_bytes_G = Arrays.copyOf(j_bytes_G, 50);
j_bytes_U = Arrays.copyOf(j_bytes_U, 50);
j_bytes_F = Arrays.copyOf(j_bytes_F, 50);
System.out.println("GBK---UTF---J_GBK---J_UTF---J_default");
//3为utf-8文件文件开始处的utf-8标记,不做文件内容处理
for (int i = 0 ;i<50-3;i++) {
System.out.println(g_bytes[i]+"---"+u_bytes[i+3]+"---"+j_bytes_G[i]+"---"+j_bytes_U[i]+"---"+j_bytes_F[i]);
}
String a_str = new String(g_bytes,0,g_len,"GBK");
//new String()默认解码方式问当前java文件的编码方式,非系统默认编码
String u_str = new String(u_bytes,3,u_len);
String g_str_j = new String(j_bytes_G,"GBK");
String u_str_j = new String(j_bytes_U);
String f_str_j = new String(j_bytes_F);
System.out.println(a_str+"******"+u_str);
System.out.println(g_str_j+"******"+u_str_j+"******"+f_str_j);
}
public static String codeString(String fileName) throws Exception{
BufferedInputStream bin = new BufferedInputStream(new FileInputStream(fileName));
int p = (bin.read() << 8) + bin.read();
String code = null;
switch (p) {
case 0xefbb:
code = "UTF-8";
break;
case 0xfffe:
code = "Unicode";
break;
case 0xfeff:
code = "UTF-16BE";
break;
default:
code = "GBK";
}
return code;
}
}
测试结果:
GBK
UTF-8
GBK---UTF---J_GBK---J_UTF---J_default
-60----28----60----28----28
-29----67----29----67----67
-54----96----54----96----96
-57----26----57----26----26
-55----104----55----104----104
-75----81----75----81----81
-79----27----79----27----27
-58----126----58----126----126
-80----69----80----69----69
-95----23----95----23----23
-80----128----80----128----128
-95----68----95----68----68
-80----27----80----27----27
-95----107----95----107----107
-80----118----80----118----118
-95----27----95----27----27
-80----107----80----107----107
-95----118----95----118----118
-80----27----80----27----27
-95----107----95----107----107
-80----118----80----118----118
-95----27----95----27----27
-71----107----71----107----107
-2----118----2----118----118
-71----27----71----27----27
-2----107----2----107----107
-71----118----71----118----118
-2----27----2----27----27
0----107---0----107----107
0----118---0----118----118
0----27---0----27----27
0----107---0----107----107
0----118---0----118----118
0----27---0----27----27
0----109---0----109----109
0----120---0----120----120
0----27---0----27----27
0----109---0----109----109
0----120---0----120----120
0----27---0----27----27
0----109---0----109----109
0----120---0----120----120
0---0---0---0---0
0---0---0---0---0
0---0---0---0---0
0---0---0---0---0
0---0---0---0---0
你是傻逼啊啊啊啊啊啊啊哈哈哈******你是傻逼啊啊啊啊啊啊啊哈哈哈
你是傻逼啊啊啊啊啊啊啊哈哈哈 ******你是傻逼啊啊啊啊啊啊啊哈哈哈 ******你是傻逼啊啊啊啊啊啊啊哈哈哈
测试文件2:UnicodeTest2.java-----该文件自身编码为GBK
package com.java.unicode;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.util.Arrays;
/**
* 本java文件编码为GBK
* */
public class UnicodeTest2 {
public static void main(String[] args) throws Exception{
String GBK_fileName = "E:\\workspace\\TestProgram\\src\\com\\java\\unicode\\GBK.txt";
String UTF_8_fileName = "E:\\workspace\\TestProgram\\src\\com\\java\\unicode\\UTF-8.txt";
String str = "你是傻逼啊啊啊啊啊啊啊哈哈哈";
System.out.println(codeString(GBK_fileName));
FileInputStream g_fis = new FileInputStream(GBK_fileName);
byte[] g_bytes = new byte[50];
int g_len = g_fis.read(g_bytes);
System.out.println(codeString(UTF_8_fileName));
FileInputStream u_fis = new FileInputStream(UTF_8_fileName);
byte[] u_bytes = new byte[50];
int u_len = u_fis.read(u_bytes);
byte[] j_bytes_G = str.getBytes("GBK");
byte[] j_bytes_U = str.getBytes("utf-8");
//str.getBytes()默认编码方式为当前java文件的编码方式,非系统默认编码
byte[] j_bytes_F = str.getBytes();
j_bytes_G = Arrays.copyOf(j_bytes_G, 50);
j_bytes_U = Arrays.copyOf(j_bytes_U, 50);
j_bytes_F = Arrays.copyOf(j_bytes_F, 50);
System.out.println("GBK---UTF---J_GBK---J_UTF---J_default");
//3为utf-8文件文件开始处的utf-8标记,不做文件内容处理
for (int i = 0 ;i<50-3;i++) {
System.out.println(g_bytes[i]+"---"+u_bytes[i+3]+"---"+j_bytes_G[i]+"---"+j_bytes_U[i]+"---"+j_bytes_F[i]);
}
String a_str = new String(g_bytes,0,g_len,"GBK");
//new String()默认解码方式问当前java文件的编码方式,非系统默认编码
String u_str = new String(u_bytes,3,u_len);
String g_str_j = new String(j_bytes_G,"GBK");
String u_str_j = new String(j_bytes_U);
String f_str_j = new String(j_bytes_F);
System.out.println(a_str+"******"+u_str);
System.out.println(g_str_j+"******"+u_str_j+"******"+f_str_j);
}
public static String codeString(String fileName) throws Exception{
BufferedInputStream bin = new BufferedInputStream(new FileInputStream(fileName));
int p = (bin.read() << 8) + bin.read();
String code = null;
switch (p) {
case 0xefbb:
code = "UTF-8";
break;
case 0xfffe:
code = "Unicode";
break;
case 0xfeff:
code = "UTF-16BE";
break;
default:
code = "GBK";
}
return code;
}
}
测试结果:
GBK
UTF-8
GBK---UTF---J_GBK---J_UTF---J_default
-60----28----60----28----60
-29----67----29----67----29
-54----96----54----96----54
-57----26----57----26----57
-55----104----55----104----55
-75----81----75----81----75
-79----27----79----27----79
-58----126----58----126----58
-80----69----80----69----80
-95----23----95----23----95
-80----128----80----128----80
-95----68----95----68----95
-80----27----80----27----80
-95----107----95----107----95
-80----118----80----118----80
-95----27----95----27----95
-80----107----80----107----80
-95----118----95----118----95
-80----27----80----27----80
-95----107----95----107----95
-80----118----80----118----80
-95----27----95----27----95
-71----107----71----107----71
-2----118----2----118----2
-71----27----71----27----71
-2----107----2----107----2
-71----118----71----118----71
-2----27----2----27----2
0----107---0----107---0
0----118---0----118---0
0----27---0----27---0
0----107---0----107---0
0----118---0----118---0
0----27---0----27---0
0----109---0----109---0
0----120---0----120---0
0----27---0----27---0
0----109---0----109---0
0----120---0----120---0
0----27---0----27---0
0----109---0----109---0
0----120---0----120---0
0---0---0---0---0
0---0---0---0---0
0---0---0---0---0
0---0---0---0---0
0---0---0---0---0
你是傻逼啊啊啊啊啊啊啊哈哈哈******浣犳槸鍌婚?鍟婂晩鍟婂晩鍟婂晩鍟婂搱鍝堝搱
你是傻逼啊啊啊啊啊啊啊哈哈哈 ******浣犳槸鍌婚?鍟婂晩鍟婂晩鍟婂晩鍟婂搱鍝堝搱 你是傻逼啊啊啊啊啊啊啊哈哈哈
注意:可以看到在两个java文件代码完全一样情况下,产生的结果却有差别。
以下结果为个人理解,并非官方权威说法,可能会有错误:
1.str.getBytes("GBK")过程是:是获取字符串转以GBK编码生成的字节码数组(外码操作),是一个用于将String的内码转换为指定的外码的方法,那么调用了String.getBytes()之后得到的byte[]只能表明该外码的性质,而无法碰触到String内码的任何特质。默认编码方式为当前java文件的编码方式;
2.str = new String(byte[],"GBK")过程是:将byte[]数组内容按GBK编码规则进行解码(外码操作),默认解码方式问当前java文件的编码方式;
3.java采用unicode编码:char在java中占2个字节。2个字节(16位)来表示一个字符。这里的Java中是指在JVM中、在内存中。在JVM内部,统一使用Unicode表示。
4.Java与Python不同,Python的字符串有两种类型(str和unicode),string类型可支持多种编码的字符串字节数组。JVM中仅支持的unicode编码,字符串在JVM中始终以unicode编码存在,虚拟机需要把各类编码的字符串转化为unicode编码,该过程JVM自动转换,对编程人员屏蔽,无法获取虚拟机中对应字符串的二进制数据。