以下是个人对java中字符和字符串的见解,如有疏漏之处,还请不吝赐教。

下面通过一个简单的程序来说明字符和字符串在Java中的旅程。

以字符 ' 中 '为例, 它的GBK编码是2个字节:0xd6d0, UTF-16 编码是2个字节:0x4e26,UTF-8编码是3个字节: 0xe4b8ab

public class CharacterInJava {public static void main(String[] args) {char c = '中';     String s = "我是一个中国人";        System.out.println(c + "" + c1 + s);
    }
}

当编辑完成CharacterInJava.java,您会选择保存文件。这时,CharacterInJava.java会保存在磁盘上。在保存的过程中,文本编辑器会帮我们将这个文件中的字符编码,我们可以指定编码,比如选择GBK编码时,字符 '中'会编码为 0xd6d0,如果是UTF-8的话,则会编码为 0xe4b8ab。下面是两种不同的编码保存文件的16进制表示:

GBK:                                                                                    UTF-8:

    

然后,我们接着要做的是编绎CharacterInJava.java, 在命令行输入javac -encoding GBK -d . CharacterInJava.java,即可编绎文件。这时可能会发生如下的错误:

错误的原因是,javac 通过-encoding 参数知道 CharacterInJava.java 是GBK编码的,因此使用GBK对源码进行解读。但其实,源码是用UTF-8编码的,因此发生了不可映射字符错误。通过更改为-encoding为UTF-8,即可编绎成功。也就是说,源文件是什么编码,程序员应该要清楚。

编绎完成后,生成了一个类文件:CharacterInJava.class,对文件进行反编绎:

Classfile /E:/JavaTutorial/IO/CharacterInJava.classLast modified 2019年2月19日; size 914 bytesMD5 checksum 5c174b19c95e5b26e64051fb06137319Compiled from "CharacterInJava.java"
public class CharacterInJavaminor version: 0major version: 53flags: (0x0021) ACC_PUBLIC, ACC_SUPERthis_class: #6                          // CharacterInJavasuper_class: #7                         // java/lang/Objectinterfaces: 0, fields: 0, methods: 2, attributes: 3
Constant pool:#1 = Methodref          #7.#16         // java/lang/Object."<init>":()V#2 = String             #17            // 我是一个中国人#3 = Fieldref           #18.#19        // java/lang/System.out:Ljava/io/PrintStream;#4 = InvokeDynamic      #0:#23         // #0:makeConcatWithConstants:(CLjava/lang/String;)Ljava/lang/String;#5 = Methodref          #24.#25        // java/io/PrintStream.println:(Ljava/lang/String;)V#6 = Class              #26            // CharacterInJava#7 = Class              #27            // java/lang/Object#8 = Utf8               <init>#9 = Utf8               ()V#10 = Utf8               Code#11 = Utf8               LineNumberTable#12 = Utf8               main#13 = Utf8               ([Ljava/lang/String;)V#14 = Utf8               SourceFile#15 = Utf8               CharacterInJava.java#16 = NameAndType        #8:#9          // "<init>":()V#17 = Utf8               我是一个中国人#18 = Class              #28            // java/lang/System#19 = NameAndType        #29:#30        // out:Ljava/io/PrintStream;#20 = Utf8               BootstrapMethods#21 = MethodHandle       6:#31          // REF_invokeStatic java/lang/invoke/StringConcatFactory.makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;#22 = String             #32            // \u0001\u0001#23 = NameAndType        #33:#34        // makeConcatWithConstants:(CLjava/lang/String;)Ljava/lang/String;#24 = Class              #35            // java/io/PrintStream#25 = NameAndType        #36:#37        // println:(Ljava/lang/String;)V#26 = Utf8               CharacterInJava#27 = Utf8               java/lang/Object#28 = Utf8               java/lang/System#29 = Utf8               out#30 = Utf8               Ljava/io/PrintStream;#31 = Methodref          #38.#39        // java/lang/invoke/StringConcatFactory.makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;#32 = Utf8               \u0001\u0001#33 = Utf8               makeConcatWithConstants#34 = Utf8               (CLjava/lang/String;)Ljava/lang/String;#35 = Utf8               java/io/PrintStream#36 = Utf8               println#37 = Utf8               (Ljava/lang/String;)V#38 = Class              #40            // java/lang/invoke/StringConcatFactory#39 = NameAndType        #33:#44        // makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;#40 = Utf8               java/lang/invoke/StringConcatFactory#41 = Class              #46            // java/lang/invoke/MethodHandles$Lookup#42 = Utf8               Lookup#43 = Utf8               InnerClasses#44 = Utf8               (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;#45 = Class              #47            // java/lang/invoke/MethodHandles#46 = Utf8               java/lang/invoke/MethodHandles$Lookup#47 = Utf8               java/lang/invoke/MethodHandles
{public CharacterInJava();descriptor: ()Vflags: (0x0001) ACC_PUBLICCode:stack=1, locals=1, args_size=10: aload_01: invokespecial #1                  // Method java/lang/Object."<init>":()V4: returnLineNumberTable:line 1: 0public static void main(java.lang.String[]);descriptor: ([Ljava/lang/String;)Vflags: (0x0009) ACC_PUBLIC, ACC_STATICCode:stack=3, locals=3, args_size=10: sipush        200133: istore_14: ldc           #2                  // String 我是一个中国人6: astore_27: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;10: iload_111: aload_212: invokedynamic #4,  0              // InvokeDynamic #0:makeConcatWithConstants:(CLjava/lang/String;)Ljava/lang/String;17: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V20: returnLineNumberTable:line 3: 0line 4: 4line 6: 7line 8: 20
}

从常量池中看到,字符串是用UTF-8编码的。从main函数中第一行sipush 20013指令看到,字符 ' 中 '是用UTF-16编码的。

也就是说,class文件的字符按照UTF-16编码,大多数的字符都是用一个代码单元就可以表示的。字符串按照UTF-8编码。下面直接在

class文件中找出这些对应的编码。0xe6 88 91 对应于 我,0x4e2d 对应于 中

接下来是运行class文件:

  查阅printfln的API知道,字符和字符串的输出,先根据平台默认的字符集将输出的字符或编码成一个或多个字节,然后将这些字节输出到终端。

整个过程大致如上,知道字符和字符串的编码,应该不易出现乱码。

转载于:https://www.cnblogs.com/yvkm/p/10400856.html

字符和字符串在Java中的旅程相关推荐

  1. 字符串在Java中_字符和字符串在Java中的旅程

    以下是个人对java中字符和字符串的见解,如有疏漏之处,还请不吝赐教. 下面通过一个简单的程序来说明字符和字符串在Java中的旅程. 以字符 ' 中 '为例, 它的GBK编码是2个字节:0xd6d0, ...

  2. 练习2-4:重新编写函数squeeze(s1,s2),将字符串s1中的任何字符与字符串时s2中的字符匹配的字符都删除

    #include <stdio.h> void squeeze(char s1[], char s2[]); int main(){/*练习2-4:重新编写函数squeeze(s1,s2) ...

  3. 一个字符多少字节在java中?

    一个字符多少字节在java中? 1. Java规定了字符的内码要用UTF-16编码,一个字符是2个字节.外码字符所占字节取决于具体编码.字符和字节是不一样的. 2. 外码编码不同,字符和字节的换算不同 ...

  4. java字符连接字符串数组_Java中连接字符串的最佳方法

    java字符连接字符串数组 最近有人问我这个问题–在Java中使用+运算符连接字符串是否对性能不利? 这让我开始思考Java中连接字符串的不同方法,以及它们如何相互对抗. 这些是我要研究的方法: 使用 ...

  5. java可变字符串替换字符,我们如何替换Java中String和StringBuffer的特定部分?

    java.lang包的String类表示一组字符.Java程序中的所有字符串文字(例如" abc")都实现为此类的实例. 例public class StringExample { ...

  6. java 字符流read函数,JAVA中文件的读写 I/O 输入输出流

    主要内容 1.编码问题 2.File类的使用 3.RandomAccessFile的使用 4.I/O 输入输出流 编码问题: 1 importjava.io.UnsupportedEncodingEx ...

  7. 字符串比较java中_java中字符串的比较

    一.  java中字符串的比较注意事项: 1.  ==: 比较的是双方的地址,而不会比较内容: 2.  compareTo: 比较的是双方的内容,而不会比较地址: 3.  equals:  进行的是字 ...

  8. java字符串数字统计_对字符串进行简单的字符数字统计 探索java中的List功能

    题目: 统计一个字符串中数字和字符串的个数,并分别进行排列,要求 1.数字,字符串可以从键盘获取. 2.储存在list 3.统计数字个数,字符串个数 4.把数字和字符串按从小到大的顺序输出 5.不能使 ...

  9. java中无效字符串,在java中从字符串中删除无效的XML字符

    到目前为止,所有这些答案只会取代字符本身.但有时XML文档会有无效的XML实体序列,从而导致错误.例如,如果 Illegal character entity: expansion character ...

最新文章

  1. HDU 4418 高斯消元法求概率DP
  2. 关于条件运算符 ?:的小程序
  3. React技术栈——webpack
  4. 推荐算法炼丹笔记:序列化推荐算法SASRec
  5. 学习《apache源代码全景分析》之常用过滤器摘录
  6. 以太坊ERC20代币合约案例
  7. Effective C# 原则42:使用特性进行简单的反射(译)
  8. 按值传递时 php必须复制值,PHP开发笔试题及答案(一)
  9. java设计模式之用王者荣耀打开观察者模式(附代码实例)每天一学设计模式
  10. 魅魔php影视系统,魅魔Maccms电影程序PHP
  11. PPT进行图片的背景去除以及填充新背景,保存图片为PDF
  12. 使用过滤器解决中文乱码问题
  13. STM32固件库点亮LED灯
  14. 安卓分析工具GameGurdian使用说明
  15. java计算机毕业设计公益诊疗系统源程序+mysql+系统+lw文档+远程调试
  16. 坚叔:让科幻片的概念变成产品丨编程挑战赛 x 嘉宾分享
  17. edge浏览器安装无法连接Internet
  18. 掌握RxJava的葵花宝典
  19. ELK日志平台搭建(一)
  20. ASP.NET程序中常用编程代码

热门文章

  1. python中的join函数连接dataframe_python pandas处理CSV文件并使用join()方法拼接两个dataframe...
  2. birt预览能有内容发布后没内容_VS Code 1.52 发布!
  3. iview select 内存泄漏_Vue遇到的内存泄漏排查处理
  4. 索佳电子水准数据传输软件_索佳全站仪数据传输软件
  5. 第三章EF的基本使用 EF添加数据实体模型
  6. linux系统给串口权限,让ubuntu串口和USB设备不用root权限访问
  7. 通过键盘事件执行查询与回填数据
  8. python keyboard库_python库 pywinio虚拟键盘使用
  9. 杭州哪里学python好_杭州哪里学python好
  10. 最短路径和最小生成树的区别