变量类型

变量类型

一、整型变量

byte < short < int < long < float < double

在 Java 中任何一个**整数型字面量**都会被默认被当做 int 类型来处理。

1
2
3
4
5
6
7
8
9
10
11
public class IntTest {
public static void main(String[] args) {
// 100 是 4 个字节,b 是八个字节。
// 所以存在自动类型类型转换。
long b=100;
// 这个不存在类型转换。
long c=100L;
// 这个会报错,原因是 = 右边先执行,这个整型字面量会以 int 类型处理,显然超过了 int 范围所以报错。其错误的原因在这。
long e=2147483648;
}
}

1.1、自动类型转换

可以理解为从小容量到大容量。程序员不需要明确地指定转换操作,而是由编程语言的规则自动执行。

1.2、 强制类型转换

大容量转换为小容量,可能会有精度损失。Java 编程语言不会自动转换,由程序员自己强制转换。

1
2
3
4
5
6
7
8
9
// 经典的例子
class Test{
public static void main(String[] args) {
int k=128;
byte e=(byte)k; //-128
int m=129;
byte n=(byte)m; -127
}
}

  • 注意:
    • 当一个整数型字面量没有超过对应变量类型范围时,可以直接赋值给对应变量类型的变量。
    • byte 和 short 混合运算的时候,先各自转换为 int 再做运算。(byte+byte–>int、 byte+short–>int、 short+short–>int)
    • 注意强转时前后都要加(),因为优先级不同。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class ByteTest {
public static void main(String[] args) {
byte b=1;
byte a=127;
// 按道理这个由 int 转换为 byte 没有强转的话因该报错。
// 其实这是 Java 语言开发者给程序员的优化措施。
// 规则:当一个整数型字面量没有超过对应变量类型范围时,可以直接赋值给对应变量类型的变量。

short m=10;
byte n=3;
// 编译器报错,最后结果是 int 类型,不能用 short 变量接收。(注意和字面量的区别)
short result=m+n;

byte c=10/3;
// 10/3 都是字面量,所以会在编译器就计算出来。即在源码 ByteTest.java 中是 byte c=10/3,但是在编译后 ByteTest.class 中 byte c=3;


byte x=10;
byte y=3;
byte d=x/y;
// 编译器报错,在编译阶段只能知道 x/y 结果为 int,只有在正式运行才知道 x,y 里面存的是什么。
}
}

二、浮点型变量

  • float:单精度,可以精确到 7 位小数。
  • double:双精度,可以精确到 15 位小数。
  • 浮点型的字面量默认当做 double 类型处理,要用 float 类型处理需要在字面量后面加 F/f。
  • 浮点型数据有两种表示形式:十进制、科学计数法。
1
2
3
4
// 不存在类型转换
float f=3.14F;
// 借助强制类型转换
float f=(float)3.14;

2.1、浮点型数据存储原理

浮点型数据存储原理涉及到计算机中的浮点数表示方法。通常情况下,浮点数由两部分组成:尾数(mantissa)和指数(exponent),以及一个符号位(sign bit),用来表示正负。

常见的浮点数表示方法是 IEEE 754 标准,它定义了单精度浮点数(32 位)和双精度浮点数(64 位)的存储格式。
在 IEEE 754 标准中,单精度浮点数的存储结构如下:

  • 符号位:1 位
  • 指数位:8 位
  • 尾数位:23 位

双精度浮点数的存储结构如下:

  • 符号位:1 位
  • 指数位:11 位
  • 尾数位:52 位

浮点数的实际值通过指数和尾数来表示。指数用来表示浮点数的数量级,尾数用来表示浮点数的精度。符号位用来表示浮点数的正负。

浮点数的存储原理基于科学计数法,即一个数可以表示为尾数乘以基数的指数次方。例如,对于单精度浮点数,可以表示为:
$$
(-1)^{\text{sign}} \times (1 + \text{mantissa}) \times 2^{\text{exponent} - \text{bias}}
$$

其中,sign 是符号位,mantissa 是尾数,exponent 是指数,bias 是偏置值(用于使指数可以表示负数)。这个公式基本上适用于双精度浮点数,只是指数偏置和尾数位数不同。

三、字符型

3.1、char

Java 中的 char 类型使用 Unicode 编码来表示字符。每个字符对应一个唯一的 Unicode 码点,可以通过 \u 后跟 4 位十六进制数来表示。

3.2、转义字符

  • \n: 换行符(newline),在输出时表示换行。
  • \t: 制表符(tab),在输出时表示水平制表。
  • \r: 回车符(carriage return),在输出时表示回车。
  • ‘: 单引号(single quote),用于表示单引号字符。
  • x Compiled from “ReadClass2.java”public class ReadClass2 {    public ReadClass2();    Code:            0: aload_0            1: invokespecial #1                  // Method java/lang/Object.”“:()V            4: return​    public static void main(java.lang.String[]);    Code:            0: bipush        10      // 向操作数栈压入 10。            2: istore_1              // 将操作数栈顶元素弹出,然后将其存储到局部变量表的 1 号槽位上。            3: iinc          1, 1    // 将局部变量表的 1 号槽位上的数加一。 此时一号槽位上的数是 11。            6: iload_1               // 将局部变量表 1 号槽位上的数据复制一份,压入操作数栈。压入的                                                                                         11。                                7: istore_2              // 将操作数栈顶元素弹出,然后将其存储到局部变量表的 2 号槽位上。            8: returnjava
  • \: 反斜杠(backslash),用于表示反斜杠字符本身。

3.3、乱码

乱码通常是由于文本数据的编码方式与解码方式不匹配或者编码过程中出现了错误所致。所以一定要保持编码与解码一致。

3.4、char 参与运算

byte、short、char 混合运算的时候,先各自转换为 int 再做运算。
多种数据类型混合运算的时候放,先各自转换为最大的再做运算。

四、boolean 类型

在 Java 中,boolean 的值只有 true、false。(与 C、C++ 有所不同)

总结:基本数据类型转换规则

1、八种基本数据类型除了 boolean 类型之外,都可以互相转换。
2、小容量可以自动转换为大容量,容量排序为:byte < short,char < int < long < float < double
3、大容量不能自动转换为小容量,必须添加强制类型转换符,才能编译通过,但是运行时可能损失精度。
4、当整数型字面量没有超过 byte、short、char 的范围时,可以将其赋值给 byte、short、char 类型的变量。
5、byte、short、char 混合运算时,各自先转换为 int 再做运算。
6、多种数据类型混合运算的时候放,先各自转换为最大的再做运算。

注意:

1、long e=2147483648; 这个属于一个经典面试题,其错误的原因是 = 右边先执行,这个整型字面量会以 int 类型处理,显然超过了 int 范围所以报错。
2、理解 byte a=10/3; 不报错,但是 byte b=10; byte c=3; a=b/3; 报错。