java常见小错误(一):变量类型自动转换与强制转换

java常见小错误(一):变量类型自动转换与强制转换

java常见错误系列文章
下一篇:java常见小错误(二):进制转换
往期文章推荐:java常见小错误(三):JAVA 交集,差集,并集


【版权申明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权);
本博客的内容来自于java常见小错误(一):变量类型自动转换与强制转换;
学习、合作与交流联系q384660495;
本博客的内容仅供学习与参考,并非营利;


文章目录

  • java常见小错误(一):变量类型自动转换与强制转换
  • 前言
  • 一、基础回顾
  • 二、各个基本类型特点
    • 1.字符型变量
    • 2.整型变量
    • 3.浮点型变量
    • 4.布尔型变量
  • 三、Java数据类型转换
    • 1.自动转换(隐式)
    • 2.强制转换(显式)
    • 3.赋值及表达式中的类型转换
      • 3.1.字面值赋值
      • 3.2.表达式中的自动类型提升
  • 总结
  • 参考资料


前言

事情发生在前几天,我的一个小伙伴问我一个问题。问题大体如下:
java常见小错误(一):变量类型自动转换与强制转换_第1张图片
这个问题本身不难理解,char型变量与int型变量相加,char型变量当然会自动转换成int类型,最后int类型赋值给char类型出错。那为什么char类型可以直接初始化一个整型数值呢?


提示:以下是本篇文章正文内容,下面案例可供参考

一、基础回顾

让我们回顾一下java中的变量类型

Q1:Java中的四大数据类型有:

1、整型

byte 、short 、int 、long

2、浮点型

float 、 double

3、字符型

char

4、布尔型

boolean


Q2:八种基本数据类型及其大小
java常见小错误(一):变量类型自动转换与强制转换_第2张图片

注意:JAVA中的数值类型不存在无符号的,它们的取值范围是固定的,不会随着机器硬件环境或者操作系统的改变而改变,这点与c语言区别开来。

二、各个基本类型特点

1.字符型变量

一般在c/c++中,char是八位二进制位,所以是占一个字节
java中的编码是unicode16的,所以一个char是16位二进制位,所以占两个字节

  • char变量的声明与初始化

代码如下(示例):

//字符,可以是汉字,因为是Unicode编码
char c1 = 'c';
//可以用整数,十进制数,八进制数,十六进制数等等赋值
char c2 = 10;
char c3 = 0b1;
char c4 = 0x5;
char c5 = 05;
//用字符的编码值来初始化
char c6 = '\u0652';
//错误示范
// char c7 = "a";
  • char类型运算

代码如下(示例):

char m = 'a';
char m1 = 'a' + 'b';//char类型相加,提升为int类型,再char范围之内则输出对应的字符。
int m2 = 'a' + 'b';//提升为int类型,结果是195。195没有超出int范围,直接输出195。
char m3 = 'a' + m;//会报错。因为m是一个赋值的变量。
char m4 = 197;//输出字符编码表中对应的字符。
char m5 = '197';//会报错。因为有单引号,表示是字符,只允许放单个字符。
char m6 = 'a' + 1;//输出结果是b。提升为int,计算结果98对应的字符是b
  • 总结
  1. 用单引号’'标识,只能放单个字符。
  2. char + char,char + int——类型均提升为int,附值char变量后,输出字符编码表中对应的字符。

这里读者会不会抱有疑问?
char+char,char+int之后类型均提升为int,为什么可以赋值给char变量,而不需要强制转换。因为int类型是比char类型大的,是不能够自动转换的。
带着这样的疑问继续向下看:

2.整型变量

  • 整型变量声明与初始化

代码如下(示例):

byte b = 1;
short s =2;
int i = 0102;
long l = 10L;

虽然byte、short、int、long 数据类型都是表示整数的,但是它们的取值范围可不一样。
byte 的取值范围:-128~127(-2的7次方到2的7次方-1)
short 的取值范围:-32768~32767(-2的15次方到2的15次方-1)
int 的取值范围:-2147483648~2147483647(-2的31次方到2的31次方-1)
long 的取值范围:-9223372036854774808~9223372036854774807(-2的63次方到2的63次方-1)
由上可以看出 byte、short 的取值范围比较小,而long的取值范围时最大的,所以占用的空间也是最多的。int 取值范围基本上可以满足我们的日常计算需求了,所以 int 也是我们使用的最多的一个整型类型。

  • java中long类型什么情况下加L?

比如long a =456 a是long类型。456是默认的int类型。int类型自动转换成long类型后面不用加L。
问题一:long类型字面值后面加L是否等于强制类型转换符?
问题二:long类型什么情况下字面值需要加L?

问题一:不是强制转换,因为int 转long是自动转的。强制转换发生在大范围变成小范围的时候。

问题二:建议只要是long类型就都加上L。见代码分析。以下代码你可以在ide编写一下,看一下情况

long a = 123;// 编译通过,因为123是int,所以被long类型的值接收没问题
long b = 123L; // 编译通过,建议这样写。
long c = 123455678123455;// 编译不通过,因为123455678123455已经超出了int的范围,这个已经不是int了,所以编译不通过
long d = 123455678123455L;// 编译通过

3.浮点型变量

  • 浮点数变量声明与初始化

与整数类型类似,Java 浮点类型也有固定的表数范围和字段长度,不受具体操作系统的影响。

浮点型常量有两种表示形式:
十进制数形式:如:5.12 512.0f .512 (必须有小数点)
科学计数法形式:如:5.12e2 512E2 100E-2

Java 的浮点型常量默认为double型,声明float型常量,须后加‘f’或‘F’。

float:单精度,尾数可以精确到7位有效数字。很多情况下,精度很难满足需求。 double:双精度,精度是float的两倍。通常采用此类型。

浮点型的数据是不能完全精确的,有时候在计算时可能出现小数点最后几位出现浮动,这时正常的。

float 和 double 都是表示浮点型的数据类型,它们之间的区别在于精确度的不同。

float(单精度浮点型)取值范围:3.402823e+38~1.401298e-45(e+38 表示乘以10的38次方,而e-45 表示乘以10的负45次方)

double(双精度浮点型)取值范围:1.797693e+308~4.9000000e-324(同上)

double 类型比float 类型存储范围更大,精度更高。

4.布尔型变量

  • 布尔型变量声明与初始化

三、Java数据类型转换

1.自动转换(隐式)

自动转换时发生扩宽(widening conversion)。因为较大的类型(如int)要保存较小的类型(如byte),内存总是足够的,不需要强制转换。如果将字面值保存到byte、short、char、long的时候,也会自动进行类型转换。注意区别,此时从int(没有带L的整型字面值为int)到byte/short/char也是自动完成的,虽然它们都比int小。在自动类型转化中,除了以下几种情况可能会导致精度损失以外,其他的转换都不能出现精度损失。

自动转换按从低到高的顺序转换。不同类型数据间的优先关系如下:
低--------------------------------------------->高
byte,short,char-> int -> long -> float -> double

 byte b = 1;
 short s = b;
 int i = s;
 char c = 10;
 long l = i;
 float f = l;
 double d = f;

这样也就解释了上面的问题,为什么可以char=char+char操作。因为字面量保存到byte、short、char、long的时候会进行自动类型转换。但是必须是字面量,而不能是已经声明的变量。

2.强制转换(显式)

如果要把大的转成小的,或者在short与char之间进行转换,就必须强制转换,也被称作缩小转换(narrowing conversion),因为必须显式地使数值更小以适应目标类型。强制转换采用转换操作符()。严格地说,将byte转为char不属于narrowing conversion),因为从byte到char的过程其实是byte–>int–>char,所以widening和narrowing都有。强制转换除了可能的精度损失外,还可能使模(overall magnitude)发生变化。

3.赋值及表达式中的类型转换

3.1.字面值赋值

在使用字面值对整数赋值的过程中,可以将int literal赋值给byte short char int,只要不超出范围。这个过程中的类型转换时自动完成的,但是如果你试图将long literal赋给byte,即使没有超出范围,也必须进行强制类型转换。例如 byte b = 10L;是错的,要进行强制转换。

3.2.表达式中的自动类型提升

除了赋值以外,表达式计算过程中也可能发生一些类型转换。在表达式中,类型提升规则如下:
· 所有byte/short/char都被提升为int。
· 如果有一个操作数为long,整个表达式提升为long。float和double情况也一样

byte b = 1;
byte d =2;
byte e = b;//均是byte类型,没问题
byte c = b+d;//出错,需要进行强制转换

总结

以上是自己的一些理解,参考了部分博主的内容。大家看到有错误的地方指出修正。希望这篇文章能对大家有所帮助。

参考资料

Java 基本数据类型 - 四类八种
Java 八大基本数据类型
Java-char类型详解
java中long类型什么情况下加L?
java数据类型转换

你可能感兴趣的:(java常见错误专栏,java)