字符和字符串在Java中的旅程
以下是个人对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中的旅程相关推荐
- 字符串在Java中_字符和字符串在Java中的旅程
以下是个人对java中字符和字符串的见解,如有疏漏之处,还请不吝赐教. 下面通过一个简单的程序来说明字符和字符串在Java中的旅程. 以字符 ' 中 '为例, 它的GBK编码是2个字节:0xd6d0, ...
- 练习2-4:重新编写函数squeeze(s1,s2),将字符串s1中的任何字符与字符串时s2中的字符匹配的字符都删除
#include <stdio.h> void squeeze(char s1[], char s2[]); int main(){/*练习2-4:重新编写函数squeeze(s1,s2) ...
- 一个字符多少字节在java中?
一个字符多少字节在java中? 1. Java规定了字符的内码要用UTF-16编码,一个字符是2个字节.外码字符所占字节取决于具体编码.字符和字节是不一样的. 2. 外码编码不同,字符和字节的换算不同 ...
- java字符连接字符串数组_Java中连接字符串的最佳方法
java字符连接字符串数组 最近有人问我这个问题–在Java中使用+运算符连接字符串是否对性能不利? 这让我开始思考Java中连接字符串的不同方法,以及它们如何相互对抗. 这些是我要研究的方法: 使用 ...
- java可变字符串替换字符,我们如何替换Java中String和StringBuffer的特定部分?
java.lang包的String类表示一组字符.Java程序中的所有字符串文字(例如" abc")都实现为此类的实例. 例public class StringExample { ...
- java 字符流read函数,JAVA中文件的读写 I/O 输入输出流
主要内容 1.编码问题 2.File类的使用 3.RandomAccessFile的使用 4.I/O 输入输出流 编码问题: 1 importjava.io.UnsupportedEncodingEx ...
- 字符串比较java中_java中字符串的比较
一. java中字符串的比较注意事项: 1. ==: 比较的是双方的地址,而不会比较内容: 2. compareTo: 比较的是双方的内容,而不会比较地址: 3. equals: 进行的是字 ...
- java字符串数字统计_对字符串进行简单的字符数字统计 探索java中的List功能
题目: 统计一个字符串中数字和字符串的个数,并分别进行排列,要求 1.数字,字符串可以从键盘获取. 2.储存在list 3.统计数字个数,字符串个数 4.把数字和字符串按从小到大的顺序输出 5.不能使 ...
- java中无效字符串,在java中从字符串中删除无效的XML字符
到目前为止,所有这些答案只会取代字符本身.但有时XML文档会有无效的XML实体序列,从而导致错误.例如,如果 Illegal character entity: expansion character ...
最新文章
- HDU 4418 高斯消元法求概率DP
- 关于条件运算符 ?:的小程序
- React技术栈——webpack
- 推荐算法炼丹笔记:序列化推荐算法SASRec
- 学习《apache源代码全景分析》之常用过滤器摘录
- 以太坊ERC20代币合约案例
- Effective C# 原则42:使用特性进行简单的反射(译)
- 按值传递时 php必须复制值,PHP开发笔试题及答案(一)
- java设计模式之用王者荣耀打开观察者模式(附代码实例)每天一学设计模式
- 魅魔php影视系统,魅魔Maccms电影程序PHP
- PPT进行图片的背景去除以及填充新背景,保存图片为PDF
- 使用过滤器解决中文乱码问题
- STM32固件库点亮LED灯
- 安卓分析工具GameGurdian使用说明
- java计算机毕业设计公益诊疗系统源程序+mysql+系统+lw文档+远程调试
- 坚叔:让科幻片的概念变成产品丨编程挑战赛 x 嘉宾分享
- edge浏览器安装无法连接Internet
- 掌握RxJava的葵花宝典
- ELK日志平台搭建(一)
- ASP.NET程序中常用编程代码
热门文章
- python中的join函数连接dataframe_python pandas处理CSV文件并使用join()方法拼接两个dataframe...
- birt预览能有内容发布后没内容_VS Code 1.52 发布!
- iview select 内存泄漏_Vue遇到的内存泄漏排查处理
- 索佳电子水准数据传输软件_索佳全站仪数据传输软件
- 第三章EF的基本使用 EF添加数据实体模型
- linux系统给串口权限,让ubuntu串口和USB设备不用root权限访问
- 通过键盘事件执行查询与回填数据
- python keyboard库_python库 pywinio虚拟键盘使用
- 杭州哪里学python好_杭州哪里学python好
- 最短路径和最小生成树的区别