编码知识点整理

编码知识点整理

编码测试

//eclipse文件编码为utf-8
public class EncodeTest {
    public static void main(String[] args) throws Exception {
        System.out.println("file_encoding:" + System.getProperty("file.encoding"));
        System.out.println("sun_jnu_encoding:" + System.getProperty("sun.jnu.encoding"));
        String temp = "龙";
        System.out.println(new String(temp.getBytes("utf-8")));
        System.out.println(temp);
    }
}

Jdk版本

E:>javac -version
javac 1.8.0_181

系统默认编码

E:>chcp
活动代码页: 936

以默认编码编译

E:>javac EncodeTest.java

cmd无法编译,根据错误信息可知编译默认采用GBK

E:>javac EncodeTest.java
EncodeTest.java:5: 错误: 编码GBK的不可映射字符
String temp = "榫?";
^
1 个错误

E:>

修改代码

//源文件编码UTF-8
public class EncodeTest {
    public static void main(String[] args) throws Exception {
        System.out.println("file_encoding:" + System.getProperty("file.encoding"));
        System.out.println("sun_jnu_encoding:" + System.getProperty("sun.jnu.encoding"));
        String temp = "你好";
        //源文件编码转换为GBK后,中文乱码如下
        //String temp = "浣犲ソ";
        System.out.println(new String(temp.getBytes("utf-8")));
        System.out.println(temp);
    }
}

以系统默认编码GBK编译源文件,运行时编码GBK

E:>javac EncodeTest.java

E:>java EncodeTest
file_encoding:GBK
sun_jnu_encoding:GBK
娴g姴銈?
浣犲ソ

运行时编码UTF-8

E:>java -Dfile.encoding=utf-8 EncodeTest
file_encoding:utf-8
sun_jnu_encoding:GBK
浣犲ソ
浣犲ソ

UTF-8编码的你好编译时使用GBK编码,变为乱码浣犲ソ,JVM以二进制字节流的形式加载class,读取字符串并构建String

运行时指定JVM采用GBK文件编码格式,JVM以GBK格式构建浣犲ソ字符串,使用UTF-8编码格式输出,变为娴g姴銈?

运行时指定JVM采用UTF-8文件编码格式,JVM以UTF-8格式构建浣犲ソ字符串,使用UTF-8编码格式输出,还是浣犲ソ

使用javap -verbose EncodeTest反编译,发现常量池里是浣犲ソ,UTF-8编码的你好编译时使用GBK编码,变为浣犲ソ

Classfile /E:/EncodeTest.class
  Last modified 2018-9-19; size 957 bytes
  MD5 checksum 85d20101a36bb26c2d43f96dad54040b
  Compiled from "EncodeTest.java"
public class EncodeTest
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #19.#30        // java/lang/Object."<init>":()V
   #2 = Fieldref           #31.#32        // java/lang/System.out:Ljava/io/PrintStream;
   #3 = Class              #33            // java/lang/StringBuilder
   #4 = Methodref          #3.#30         // java/lang/StringBuilder."<init>":()V
   #5 = String             #34            // file_encoding:
   #6 = Methodref          #3.#35         // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   #7 = String             #36            // file.encoding
   #8 = Methodref          #31.#37        // java/lang/System.getProperty:(Ljava/lang/String;)Ljava/lang/String;
   #9 = Methodref          #3.#38         // java/lang/StringBuilder.toString:()Ljava/lang/String;
  #10 = Methodref          #39.#40        // java/io/PrintStream.println:(Ljava/lang/String;)V
  #11 = String             #41            // sun_jnu_encoding:
  #12 = String             #42            // sun.jnu.encoding
  #13 = String             #43            // 浣犲ソ
  #14 = Class              #44            // java/lang/String
  #15 = String             #45            // utf-8
  #16 = Methodref          #14.#46        // java/lang/String.getBytes:(Ljava/lang/String;)[B
  #17 = Methodref          #14.#47        // java/lang/String."<init>":([B)V
  #18 = Class              #48            // EncodeTest
  #19 = Class              #49            // java/lang/Object
  #20 = Utf8               <init>
  #21 = Utf8               ()V
  #22 = Utf8               Code
  #23 = Utf8               LineNumberTable
  #24 = Utf8               main
  #25 = Utf8               ([Ljava/lang/String;)V
  #26 = Utf8               Exceptions
  #27 = Class              #50            // java/lang/Exception
  #28 = Utf8               SourceFile
  #29 = Utf8               EncodeTest.java
  #30 = NameAndType        #20:#21        // "<init>":()V
  #31 = Class              #51            // java/lang/System
  #32 = NameAndType        #52:#53        // out:Ljava/io/PrintStream;
  #33 = Utf8               java/lang/StringBuilder
  #34 = Utf8               file_encoding:
  #35 = NameAndType        #54:#55        // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  #36 = Utf8               file.encoding
  #37 = NameAndType        #56:#57        // getProperty:(Ljava/lang/String;)Ljava/lang/String;
  #38 = NameAndType        #58:#59        // toString:()Ljava/lang/String;
  #39 = Class              #60            // java/io/PrintStream
  #40 = NameAndType        #61:#62        // println:(Ljava/lang/String;)V
  #41 = Utf8               sun_jnu_encoding:
  #42 = Utf8               sun.jnu.encoding
  #43 = Utf8               浣犲ソ
  #44 = Utf8               java/lang/String
  #45 = Utf8               utf-8
  #46 = NameAndType        #63:#64        // getBytes:(Ljava/lang/String;)[B
  #47 = NameAndType        #20:#65        // "<init>":([B)V
  #48 = Utf8               EncodeTest
  #49 = Utf8               java/lang/Object
  #50 = Utf8               java/lang/Exception
  #51 = Utf8               java/lang/System
  #52 = Utf8               out
  #53 = Utf8               Ljava/io/PrintStream;
  #54 = Utf8               append
  #55 = Utf8               (Ljava/lang/String;)Ljava/lang/StringBuilder;
  #56 = Utf8               getProperty
  #57 = Utf8               (Ljava/lang/String;)Ljava/lang/String;
  #58 = Utf8               toString
  #59 = Utf8               ()Ljava/lang/String;
  #60 = Utf8               java/io/PrintStream
  #61 = Utf8               println
  #62 = Utf8               (Ljava/lang/String;)V
  #63 = Utf8               getBytes
  #64 = Utf8               (Ljava/lang/String;)[B
  #65 = Utf8               ([B)V
{
  public EncodeTest();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 1: 0

  public static void main(java.lang.String[]) throws java.lang.Exception;
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=5, locals=2, args_size=1
         0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: new           #3                  // class java/lang/StringBuilder
         6: dup
         7: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V
        10: ldc           #5                  // String file_encoding:
        12: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        15: ldc           #7                  // String file.encoding
        17: invokestatic  #8                  // Method java/lang/System.getProperty:(Ljava/lang/String;)Ljava/lang/String;
        20: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        23: invokevirtual #9                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        26: invokevirtual #10                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        29: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        32: new           #3                  // class java/lang/StringBuilder
        35: dup
        36: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V
        39: ldc           #11                 // String sun_jnu_encoding:
        41: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        44: ldc           #12                 // String sun.jnu.encoding
        46: invokestatic  #8                  // Method java/lang/System.getProperty:(Ljava/lang/String;)Ljava/lang/String;
        49: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        52: invokevirtual #9                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        55: invokevirtual #10                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        58: ldc           #13                 // String 浣犲ソ
        60: astore_1
        61: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        64: new           #14                 // class java/lang/String
        67: dup
        68: aload_1
        69: ldc           #15                 // String utf-8
        71: invokevirtual #16                 // Method java/lang/String.getBytes:(Ljava/lang/String;)[B
        74: invokespecial #17                 // Method java/lang/String."<init>":([B)V
        77: invokevirtual #10                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        80: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        83: aload_1
        84: invokevirtual #10                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        87: return
      LineNumberTable:
        line 3: 0
        line 4: 29
        line 5: 58
        line 6: 61
        line 7: 80
        line 8: 87
    Exceptions:
      throws java.lang.Exception
}
SourceFile: "EncodeTest.java"

WinHex查看class文件

mark

以UTF-8对源文件编码,运行时编码为GBK

E:>javac -encoding utf-8 EncodeTest.java

E:>java EncodeTest
file_encoding:GBK
sun_jnu_encoding:GBK
浣犲ソ
你好

E:>java -Dfile.encoding=utf-8 EncodeTest
file_encoding:utf-8
sun_jnu_encoding:GBK
你好
你好

UTF-8编码的你好编译时使用UTF-8编码,class文件常量池里面是你好

运行时指定JVM采用GBK文件编码格式,JVM以GBK格式构建你好字符串,使用UTF-8编码格式输出,变为浣犲ソ

运行时指定JVM采用UTF-8文件编码格式,JVM以UTF-8格式构建你好字符串,使用UTF-8编码格式输出,还是你好

反编译javap -verbose EncodeTest后,常量池内是你好

WinHex查看class文件

mark

参考资料

https://blog.csdn.net/u010234516/article/details/52842170

posted @ 2018-09-20 10:03  龍變  阅读(477)  评论(0编辑  收藏  举报