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

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

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

public classCharacterInJava {public static voidmain(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日; size914bytes

MD5 checksum 5c174b19c95e5b26e64051fb06137319

Compiled from"CharacterInJava.java"

public classCharacterInJava

minor version:0major version:53flags: (0x0021) ACC_PUBLIC, ACC_SUPER

this_class: #6 //CharacterInJava

super_class: #7 //java/lang/Object

interfaces: 0, fields: 0, methods: 2, attributes: 3Constant pool:

#1 = Methodref #7.#16 //java/lang/Object."":()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 #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 //"":()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

{publicCharacterInJava();

descriptor: ()V

flags: (0x0001) ACC_PUBLIC

Code:

stack=1, locals=1, args_size=1

0: aload_01: invokespecial #1 //Method java/lang/Object."":()V

4: returnLineNumberTable:

line1: 0

public static voidmain(java.lang.String[]);

descriptor: ([Ljava/lang/String;)V

flags: (0x0009) ACC_PUBLIC, ACC_STATIC

Code:

stack=3, locals=3, args_size=1

0: sipush 20013

3: 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;)V

20: returnLineNumberTable:

line3: 0line4: 4line6: 7line8: 20}

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

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

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

接下来是运行class文件:

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

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

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

  1. java中的字符,字符串,数字之间的转换(亲测)

    string 和int之间的转换 string转换成int  :Integer.valueOf("12") int转换成string : String.valueOf(12) ch ...

  2. java中的字符,字符串,数字之间的转换

    java中的字符,字符串,数字之间的转换 string 和int之间的转换 string转换成int :Integer.valueOf(" ") int转换成string : St ...

  3. 字符中搜索字符或者字符串

      CHARINDEX和PATINDEX函 数常常用来在一段字符中搜索字符或者字符串.如果被搜索的字符中包含有要搜索的字符,那么这两个函数返回一个非零的整数,这个整数是要搜索的字符在被搜索 的字符中的 ...

  4. 每天一道LeetCode-----在字符串s中找到最短的包含字符串t中所有字符的子串,子串中字符顺序无要求且可以有其他字符

    Minimum Window Substring 原题链接Minimum Window Substring 要求在源字符串s中找到长度最短的子串,这个子串包含目标字符串t中的所有字符,字符顺序没有要求 ...

  5. C语言中的字符和字符串

    C语言在中常常出现字符和字符串,而一串字符或者字符串其实就是数组 字符数组的定义 char arr[]={'h','e','l','l','o','\0'}; 而定义字符串: char arr1[]= ...

  6. C#中的字符与字符串

    Char Char在C#中表示一个Unicode字符,正是这些Unicode字符构成了字符串.Unicode字符是目前计算机通用的字符编码,它为针对不同的语言的每个字符设定了统一的二进制编码,用于满足 ...

  7. java 将中文字符转为英文,java 将中文字符号转为英文

    java 将中文字符转为英文,java 将中文字符号转为英文 package test;import java.io.UnsupportedEncodingException;public class ...

  8. 细说Java中的字符和字符串(一)

    #一道经典问题 Java里的char类型能不能存储一个中文字符? 对于这道题,绝大多数的答案都是"可以存储".给出的原因包括: java中的char是unicode存储,unico ...

  9. java 输入任何字符继续_Thinking in Java 4th chap13笔记-字符串

    1.JavaSE5推出了C语言printf风格的格式化输出这一功能.这不仅使得控制输出的代码更加简单,而且也给与Java开发者对于输出格式与排列的更强大的控制能力. 2.C语言printf,占位符-如 ...

最新文章

  1. Qt for Python之 PySide2+QML 入门示例
  2. 零基础学Python(第十三章 元组)
  3. Cisco packet tracer6.0下的网络工程实训
  4. pythonnet下载_Python for .NET
  5. sourcetree不好做到的一些git操作
  6. Cisco公司的CAR流量控制策略
  7. vue读取Excel并分组处理数据显示
  8. 《你必须知道的.NET》读书实践:一个基于OO的万能加载器的实现
  9. Python关键词百度指数采集,抓包Cookie及json数据处理
  10. 信息系统项目管理师必背核心考点(六十)项目集管理
  11. 简说window操作系统
  12. 【附源码】计算机毕业设计SSM网上旅游订票服务系统
  13. flask 发送新浪邮箱邮件
  14. 循序渐进全球化 镜像识别
  15. 企业电子招标采购系统源码+ 前后端分离 + 二次开发+Spring Cloud
  16. uniapp点击时出现背景声音
  17. java计算机毕业设计课题申报系统MyBatis+系统+LW文档+源码+调试部署
  18. 大神用python爬取天气信息并且语言播报
  19. MarkDown如何打出反引号
  20. 离开学校如何成为网页设计师1

热门文章

  1. Vue-Cli4笔记
  2. android surfaceflinger 代码,Android 中的framebuffer和SurFaceFlinger的关系
  3. Java 并发(Future 模式)
  4. Java IDEA使用详解
  5. 列出最少8种开源软件_您的公司可以支持和维持开源的8种方式
  6. 无论您的工作职能如何,如何获得功绩
  7. openstack 学习_需要IT工作吗? 学习OpenStack
  8. 类和模块 类和原型 工厂方法 构造函数 constructor
  9. Bootstrap导航中禁用导航链接
  10. Bootstrap 导航条的组件