# Java 八大基本数据类型
数据类型 | 大小 | 默认值 | 取值范围 | 描述 |
---|---|---|---|---|
byte | 1 字节 | 0 | -128 到 127 | 有符号整数 |
short | 2 字节 | 0 | -32,768 到 32,767 | 有符号整数 |
int | 4 字节 | 0 | -2,147,483,648 到 2,147,483,647 | 有符号整数 |
long | 8 字节 | 0L | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 | 有符号整数 |
float | 4 字节 | 0.0f | 1.4E-45 到 3.4028235E38 | 浮点数 |
double | 8 字节 | 0.0d | 4.9E-324 到 1.7976931348623157E308 | 双精度浮点数 |
char | 2 字节 | '\u0000' | '\u0000' 到 '\uffff' (0 到 65,535) | Unicode 字符 |
boolean | 没有固定大小 | false | true 或 false | true 或 false 值 |
# Java 基本数据类型对应的包装类
数据类型 | 对应包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
# 包装类常用方法和特别设计
Byte
- 常用方法:valueOf (byte b)、byteValue ()、compareTo (Byte anotherByte)、equals (Object obj)、toString ()、hashCode ()
- 特别设计:缓存了 - 128~127 之间的所有 Byte 对象,可以使用 Byte.valueOf (byte b) 方法直接返回缓存的对象,避免重复创建对象
Short
- 常用方法:valueOf (short s)、shortValue ()、compareTo (Short anotherShort)、equals (Object obj)、toString ()、hashCode ()
- 特别设计:缓存了 - 128~127 之间的所有 Short 对象,可以使用 Short.valueOf (short s) 方法直接返回缓存的对象,避免重复创建对象
Integer
- 常用方法:valueOf (int i)、intValue ()、compareTo (Integer anotherInteger)、equals (Object obj)、toString ()、hashCode ()
- 特别设计:缓存了 - 128~127 之间的所有 Integer 对象,可以使用 Integer.valueOf (int i) 方法直接返回缓存的对象,避免重复创建对象
Long
- 常用方法:valueOf (long l)、longValue ()、compareTo (Long anotherLong)、equals (Object obj)、toString ()、hashCode ()
- 特别设计:缓存了 - 128~127 之间的所有 Long 对象,可以使用 Long.valueOf (long l) 方法直接返回缓存的对象,避免重复创建对象
Float
- 常用方法:valueOf (float f)、floatValue ()、compareTo (Float anotherFloat)、equals (Object obj)、toString ()、hashCode ()
- 特别设计:没有特别设计
Double
- 常用方法:valueOf (double d)、doubleValue ()、compareTo (Double anotherDouble)、equals (Object obj)、toString ()、hashCode ()
- 特别设计:没有特别设计
Character
- 常用方法:valueOf (char c)、charValue ()、compareTo (Character anotherCharacter)、equals (Object obj)、toString ()、hashCode ()
- 特别设计:缓存了 0~127 之间的所有 Character 对象,可以使用 Character.valueOf (char c) 方法直接返回缓存的对象,避免重复创建对象
Boolean
- 常用方法:valueOf (boolean b)、booleanValue ()、compareTo (Boolean anotherBoolean)、equals (Object obj)、toString ()、hashCode ()
- 特别设计:缓存了 Boolean 类型的 TRUE 和 FALSE 两个对象
当 Java 自动装箱时,会重用对象,将一些常见的包装类对象缓存起来以提高性能和降低内存占用。下面是几个常用的包装类缓存示例:
# 包装类缓存示例
- Integer 类的缓存示例:
Integer a = 10; | |
Integer b = 10; | |
System.out.println(a == b); //true,因为 10 在缓存范围内 | |
Integer c = 128; | |
Integer d = 128; | |
System.out.println(c == d); //false,因为 128 不在缓存范围内 |
解释:在 Integer 类中,缓存了 -128 到 127 的 Integer 对象。因此,当值为在这个范围内时,自动装箱后的对象会直接从缓存中获取,而不是新建一个对象。因此,a 和 b 的值都是 10,因为它们共享了同一个对象,所以比较时结果为 true。而 c 和 d 的值都是 128,但由于它们不在缓存范围内,所以自动装箱后会新建两个对象,所以比较时结果为 false。
- Boolean 类的缓存示例:
Boolean a = true; | |
Boolean b = true; | |
System.out.println(a == b); //true,因为 true 和 false 都有缓存 | |
Boolean c = false; | |
Boolean d = false; | |
System.out.println(c == d); //true,因为 true 和 false 都有缓存 |
解释:在 Boolean 类中,缓存了 true 和 false 两个对象。因此,当自动装箱时,这两个对象会直接从缓存中获取,而不是新建对象。因此,a 和 b 都是 true,且共享了同一个对象,所以比较时结果为 true。而 c 和 d 都是 false,且共享了同一个对象,所以比较时结果为 true。
- Character 类的缓存示例:
Character a = 'a'; | |
Character b = 'a'; | |
System.out.println(a == b); //true,因为 a 在缓存范围内 | |
Character c = '中'; | |
Character d = '中'; | |
System.out.println(c == d); //false,因为 ' 中 ' 不在缓存范围内 |
解释:在 Character 类中,缓存了 Unicode 编码从 0 到 127 的字符。因此,当自动装箱时,这些字符会直接从缓存中获取,而不是新建对象。因此,a 和 b 的值都是 'a',且共享了同一个对象,所以比较时结果为 true。而 c 和 d 的值都是 ' 中 ',但由于它们不在缓存范围内,所以自动装箱后会新建两个对象,所以比较时结果为 false。
需要注意的是,虽然自动装箱时会重用对象,但如果使用构造函数手动创建对象,则不会使用缓存,每次都会新建一个对象。
# 包装类对象的相互转化
当我们需要在基本数据类型和包装类之间进行转换时,可以使用 Java 中提供的自动装箱和自动拆箱机制,也可以手动调用包装类提供的转换方法。以下是一些常见的基本数据类型和包装类之间的转换示例:
- 基本数据类型转换成对应的包装类:
int num = 10; | |
Integer numWrapper = Integer.valueOf(num); |
- 包装类转换成对应的基本数据类型:
Double doubleWrapper = new Double(3.14); | |
double num = doubleWrapper.doubleValue(); |
- 使用自动装箱和自动拆箱:
int num = 100; | |
Integer numWrapper = num; // 自动装箱 | |
int newNum = numWrapper; // 自动拆箱 |
- 字符串转换成包装类:
String str = "123"; | |
Integer numWrapper = Integer.valueOf(str); |
- 包装类转换成字符串:
Integer numWrapper = new Integer(123); | |
String str = numWrapper.toString(); |
需要注意的是,在进行基本数据类型和字符串之间的转换时,也可以使用 parseInt()
和 valueOf()
等方法。例如:
int num = Integer.parseInt("123"); | |
String str = Integer.toString(123); |
# 自动装箱和自动拆箱
在 Java 中,自动装箱和自动拆箱是指基本数据类型与其对应的包装类之间的自动转换,使得它们在使用上可以互相替换,从而使代码更加简洁和易读。
具体来说,自动装箱是指将基本数据类型自动转换为对应的包装类,而自动拆箱则是指将包装类自动转换为对应的基本数据类型。这样一来,程序员在使用时就无需手动进行类型转换,编译器会自动帮助完成。
下面是自动装箱和自动拆箱的示例代码:
// 自动装箱 | |
Integer i = 10; // 相当于 Integer i = Integer.valueOf (10); | |
// 自动拆箱 | |
int j = i; // 相当于 int j = i.intValue (); |
从上面的示例代码可以看出,自动装箱和自动拆箱让代码更加简洁,减少了程序员的工作量,提高了代码的可读性和可维护性。
其原理是编译器自动在编译时将代码进行转换。对于自动装箱,编译器会将基本数据类型转换为对应的包装类类型,调用相应的 valueOf 方法进行装箱;对于自动拆箱,编译器会将包装类类型转换为对应的基本数据类型,调用相应的 xxxValue 方法进行拆箱。这样一来,程序员就可以像操作基本数据类型一样操作包装类类型了。
需要注意的是,自动装箱和自动拆箱虽然方便了编程,但是也会带来性能问题。在大量使用时,建议手动进行类型转换,以提高程序性能。
# 其他注意项
- 类型转换:Java 中的数据类型有不同的大小和精度,如果将一个大的数据类型转换为一个小的数据类型,会导致数据精度的丢失,这就需要进行类型转换。类型转换可以分为隐式类型转换和显式类型转换两种。
- final 关键字:final 关键字可以用来修饰变量、方法和类。final 修饰的变量不能被修改,final 修饰的方法不能被覆盖,final 修饰的类不能被继承。对于基本数据类型,final 修饰的变量必须被初始化,一旦被初始化后就不能再次被修改。
- 枚举类型:Java 中的枚举类型可以列出一组常量,并为这些常量赋予特定的值。枚举类型可以用来取代常量,使代码更加可读和易于维护。枚举类型也是一种特殊的类,可以有构造函数、方法和字段。
- 变量作用域:在 Java 中,变量有不同的作用域,变量的作用域决定了变量在程序中可以被访问的范围。Java 中有四种作用域:类作用域、方法作用域、块作用域和局部作用域。
- 常量池:Java 中的常量池是指在编译时确定的、存储在.class 文件中的常量集合。常量池中可以包含字符串、数字、类名、方法名等常量。Java 的数据类型也有对应的常量池,例如 Integer 类型的常量池中包含了 - 128~127 之间的整数。常量池可以提高程序的运行效率,减少内存的占用。
这些内容也是 Java 数据类型中比较重要的一些方面,需要开发者在日常的开发中注意。