char强制类型转换为int_数据类型专题之三: char类型和类型转换

本文讲解Java中的char类型特点及Unicode编码,介绍类型转换的方法,并探讨不同编码的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这是数据类型专题最后一个部分,包含了最后一个基本类型char类型和类型转换的知识。像这样的专题内容,小猿会在期中考试之前整理成pdf格式放送给各位老粉的,现在关注你也是老粉!

char 类型

char类型是字符类型。占16 bits 空间,取值范围为[0,65535],char类型很简单,有趣的是char类型背后的编码。Java的char类型采用的是Unicode编码。

可以通过以下方式查看某个字符的Unicode编码(比如这两天经常困扰同学们的中文引号和括号),Unicode用四位十六进制数字表示:

public static void main(String[] args){
 char c1 = ')';
 char c2 = '“';
 System.out.format("%x",(int)c1);
 System.out.format("%x",(int)c2);
}/*output:
ff09
201c
*/

也可以通过编码获得字符(需要通过\u进行转义):

public static void main(String[] args){
 char c1 = '\u0056';
 char c2 = '\u0057';
 System.out.println(c1+" "+c2)
}/*output:
V M
*/

看到这里,小猿相信同学就能明白char类型为什么本质上还是一个整数类型了。而多个char类型连续的拼在一起,就是String类型

(选读)编码

众所周知,计算机只能储存二进制数字,想要让计算机储存字符,必须制订一套将数字和字符一一对应的标准,在读出数字之后通过映射关系获得字符,这种标准就被称为编码 (character encoding standard)。编码的早期形态就是 ASCII (American Standard Code for Information Interchange) 。ASCII标准中一个字符占据 8 bits 空间,理论上 ASCII 编码可以包含 255 个字符 ,足以编码大部分拉丁语系的语言,但是当计算机逐渐推广到全世界,哪怕只和繁星一般多的汉字相比,ASCII编码可怜的容量就已经相形见绌了,更不要说日语,印度文等语言了。

为了解决拉丁语系外的语言的编码问题 “万国码” - Unicode诞生了,Unicode的宗旨是将世界上的所有语言中的字符乃至数学符号进行编码。一单位Unicode本身含有16个bits,在表示时使用4位16进制数字。单个Unicode标准下的char类型称为单位(unit),而字符则被称为码点 (code point),由于编码进Unicode的字符越来越多,[0,65535]的容量已经不够了,于是Unicode就增加了两个单位表示一个码点的机制,这样,理论上Unicode的容量就扩大了大概 倍,足以编码所有世界上现有的以及未来产生的字符了。

但是Unicode追求的是大和全,其代价是成倍增长的储存空间占用,这给网络带来了很大的负担。于是基于Unicode,人们又发展出了各种UTF (Unicode Transformation Format) 编码版本,其中最常用的当数UTF-8编码,UTF-8编码单个单元占据 8 bits,但是其采用一种变长编码的策略,这使得UTF-8编码包含了大部分常用字符的同时具有很好的空间利用效率。同时,UTF-8编码的前 8 bits 是兼容ASCII编码的。

除了国际编码,各国也有本国语言专用的编码。GBK系列就是基于ASCII发展出来的专门编码汉字的编码,其在储存和传输汉字方面比UTF-8更加实惠。

类型转换

我们讨论类型转换时,一般所指的是 8 种基本类型和String类型一共9种类型间的相互转换。

安全的类型转换

类型转换 (casting) 的本质是改变数据在底层的储存方式,由于每种数据有其范围和精确度,从小范围,低精确度的数据类型转向大范围,高精确度的数据类型是安全的8种基本数据类型的范围,精确度从小(低)到大(高)排名为 boolean,byte,short = char,int ,long float,double。这种安全的转换存在于8种基本类型之间,而且往往是自动(隐式)完成的:

double d = 1.0/8;//int 转为 double
int i = 'a';//char 转为 int
int c1 = '\u0056';//char 转为 int
long l = 38912;//int 转为 long
double d = 232l;//long 转为 double

以上这些语句出现在代码中时,不会有任何警告和错误。

强制类型转换

从大范围,高精确度的数据类型转向小范围,低精确度的数据类型是有风险的,因为这样的做法很可能会导致数据的丢失。

int i = 1000000000000l;//error

d9ccc9788e48d14c08d66489da9f4d2e.png

这种语句在运行之前IDE就会发出警告,强行运行的话会导致编译时期错误。

a89597dbca23d4fdf3229debce215007.png

想要完成这种转型,必须使用强制类型转换,语法非常简单,就是在变量/字面量前加用一对括号包围的数据类型:

int i = (int)1000000000000l
System.out.println(i);
/*output:
-727379968
*/

可以看到,以上的这个强制转型产生了非常严重的精度损失。强制转型有很大的风险,没有充足的把握不要使用强制转型,更不要为了能通过编译使用强制转型!

基本类型和String类型的转换

在以往的推文中,小猿提到过:

517e3e6bcb526f49c13ca9e9d05458e5.png

从基本类型转到 String

为了使Java面向对象的版图完整,Java官方库提供了包装类(wrapper class),8个基本类型有8个对应的包装类:Integer Byte Long Short Character Double Float Boolean,这8个类从属于 java.lang包,不需要手动import(java.lang包在所有的java源码中被隐式地引用)。在Java中,每个对象都有用toString()方法,每个包装类的toString()方法有两种调用方式:

Integer i = 100;
String s1 = Integer.toString(i);
String s2 = i.toString();

其他的包装类类推即可。当然,也可以使用 String.valueOf() 方法。

从String到基本类型

这个情况在处理输入时比较常见,比如用户输入了一串数字字符串,我么需要将其转换成数字。强大的Java官方库提供了现成的方法:

int i = Integer.parseInt("12378");

这样的现成的函数在java中基本上每个基本类型都有,小猿就留给同学们自己探索了。如果在c语言中,这个问题就比较痛苦了,需要用循环一位一位的处理,可见官方库对一门语言易用程度的影响。

有任何Java学习相关的问题,或者找到了文章中的错误,可以在公众号后台给小猿留言哦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值