目录
总览:
字节数及范围:
简述:
整型:
浮点型:
字符型:
布尔类型:
Java基本数据类型变量/常量 初始化/赋值问题
类型转换:
int 和 long/double之间的转换:
int 和 boolean类型:
byte和int类型的转换:
long和double之间
类型提升:
int -> float -> double
byte short int long
基本数据类型变量初始化/赋值时的范围检查:
常量
字面值常量:
2. final 关键字修饰的常量
一共八种基本数据类型,简单清楚。
整型: byte 字节类型 short 短整型 int 整型 long 长整型
浮点型: float 单精度浮点型 double 双精度浮点型
字符类型: char 字符型
布尔类型: boolean 布尔型
整型:
字节类型byte: 1字节 -128~127
短整型short: 2字节 - 2^15 ~ 2^15 -1 -32768 ~ 32767
整型int: 4字节 -2^31 ~ 2^31-1 -21亿~21亿
长整型: 8字节 -2^63 ~ 2^63-1 范围略 19位数字
浮点型:
双精度浮点型double:8字节。精度较高
单精度浮点型float: 4字节。精度较低
字符类型char: 2字节 对应的整数范围:0 ~ 65535
布尔类型boolean: 未定,1or2字节,多处1字节?
==== Java中上述基本数据类型所占内存大小,字节数,是和环境,系统没有关系的。也就是固定不变的。这也是Java可移植性强的原因。而C/C++则没有此优点。
可以看到,字节类型可存储的范围很小,只有-128~127。并且新手在日常使用中可能用int最多。并且短整型范围也只有-3万~3万。在一般的工程中并不多使用。
Java是一个较为安全的语言相比于C/C++。如果给byte,short,int,long类型的变量或常量赋一个超出范围的值,就会报错。导致代码编译不过去。
对于long类型变量的初始化或赋值,最好要赋值一个long字面值常量,比如215L 210L等。而形如210 220等都是int字面值常量(十进制)。long字面值常量后方的L可小写,建议大写,清晰。 也就是说,程序中书写的整数,默认为int型字面值常量。而若进行如下定义:
long l1 = 2200000000; 就会报错,因为2200000000超出了int的范围,解决方法是在后方加L/l
整型这里还有整型提升的问题,从属于类型提升。后方讲解。
单精度浮点型整体来看精度并不是很高。通常用double更为合适。
程序中书写的1.0 2.5等都是double字面值常量,相当于 1.0d 2.5D 而1.5f 2.5F则是float字面值常量。
由于Java的安全性。float f = 2.5;是无法编译通过的。因为将double值赋给float值是可能丢失精度,不安全的。所以float f = 2.5f; 是正确的初始化方式。这里和int与long相似。
char类型可以用字符直接初始化,也可以用整数初始化。但是需要注意范围。0~65535。
Java中字符类型使用的是unicode字符编码,不同于C/C++中char的ASCII码。unicode表示的字符范围更广,包括了汉字等。也因此Java中char类型的大小为2字节。 unicode和utf-8 utf-16等有直接关系。暂不了解。
Java中布尔类型的初始值只能是true or false 且在Java中 ,if条件判断部分和for,&&逻辑与,||逻辑或,等条件判断部分的表达式结果都必须是一个boolean类型。没有0表示假,非0表示真的逻辑,这是与C/C++不同的。
这里的true/false。你可以直接理解为逻辑上的真 或 假。它们与整数之间没有任何关系。所以互相之间不能赋值,强制类型转换也不可以。
Java中,基本数据类型的变量不初始化,不可以使用(表达式中或者打印),都是错误的。无法编译通过。Java 很 安 全 省 心。
并且final修饰的变量可以先定义,不初始化,之后再初始化。但是在第一次初始化之后,就定了此常量的值了,不可以进行第二次初始化。我记得C/C++中常量不能定义之后再初始化。
Java 作为一个强类型编程语言, 当不同类型之间的变量相互赋值的时候, 会有较严格的校验。
long 表示的范围更大, 可以将 int 赋值给 long, 但是不能将 long 赋值给 int.因为不安全
double 表示的范围更大, 可以将 int 赋值给 double, 但是不能将 double 赋值给 int.因为不安全
结论: 不同数字类型的变量之间赋值, 表示范围更小的类型能隐式转换成范围较大的类型, 反之则不行.
图中结果是超出int范围的long类型变量强转为int后赋值给int的结果。会发生意料不到的结果,但是可以编译通过。
Java中整型和布尔类型是完全不相关的类型,布尔类型仅仅仅仅仅仅表示真或假,true or false。与数值没有任何关系。不能相互赋值。并且,无任何联系的两个类型之间不能强转。
其实道理和int与long是一样的,因为byte short int long之间大体上只是存储的整数的范围不同而已。其他没什么区别。相互赋值的统一原则就是:大范围赋值给小范围可能出现错误,所以不安全,所以禁止。小范围赋值给大范围是安全的,所以允许。
由上方经验,好像小范围赋值给大范围永远是对的。但这仅在同类型数值类型之间,如整型家族之间。而8字节的long是不能被float赋值的。其实这也是合理的,因为不强转,那浮点型转换为整型势必会丢失精度。很不安全。 这些好像没有太大意义了...
由上述代码可知,int + float int会提升为float。 int + double 会提升为double。
而标红处的强转是因为不强转是无法编译通过的。
由上述代码可知,float与double进行某些运算时(并非仅加减)会提升为double。其实道理都是一样的。
由于计算机的 CPU 通常是按照 4 个字节为单位从内存中读写数据. 为了硬件上实现方便, 诸如 byte 和 short 这种低于 4 个字节的类型, 会先提升成 int, 再参与计算.
(int 和 long :int 与 long进行运算,int提升为long,但 int = int + int不会隐式类型转换)
总结:
其实这部分和C/C++中的类型提升非常相似。= =
Java的安全性:
byte short int long 等类型的变量进行初始化/赋值时,都会对赋值运算符右边的字面值常量进行进行检查,超出范围的会报错。 很安全!很放心!
包括 char类型也会检查,其实这部分内容在上方某些地方都有或多或少的介绍。
10 // int 字面值常量(十进制)
010 // int 字面值常量(八进制) 由数字 0 开头. 010 也就是十进制的 8
0x10 // int 字面值常量(十六进制) 由数字 0x 开头. 0x10 也就是十进制的 16
10L // long 字面值常量. 也可以写作 10l (小写的L)
1.0 // double 字面值常量. 也可以写作 1.0d 或者 1.0D
1.5e2 // double 字面值常量. 科学计数法表示. 相当于 1.5 * 10^2
1.0f // float 字面值常量, 也可以写作 1.0F
true // boolen 字面值常量, 同样的还有 false
'a' // char 字面值常量, 单引号中只能有一个字符
"abc" // String 字面值常量, 双引号中可以有多个字符.
final int a = 10;
a = 20; // 编译出错. 提示 无法为最终变量a分配值
常量不能在程序运行过程中发生修改.
=====================================
每种数据类型及其范围, 是需要我们掌握的重点. 隐式类型转换和类型提升, 是本节的难点. 但是一般我们更推荐在代码中避免不同类型混用的情况, 来规避类型转换和 类型提升的问题.