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 自动装箱时,会重用对象,将一些常见的包装类对象缓存起来以提高性能和降低内存占用。下面是几个常用的包装类缓存示例:

包装类缓存示例

  1. 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。

  1. 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。

  1. 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 中提供的自动装箱和自动拆箱机制,也可以手动调用包装类提供的转换方法。以下是一些常见的基本数据类型和包装类之间的转换示例:

  1. 基本数据类型转换成对应的包装类:
int num = 10;
Integer numWrapper = Integer.valueOf(num);
  1. 包装类转换成对应的基本数据类型:
Double doubleWrapper = new Double(3.14);
double num = doubleWrapper.doubleValue();
  1. 使用自动装箱和自动拆箱:
int num = 100;
Integer numWrapper = num; // 自动装箱
int newNum = numWrapper; // 自动拆箱
  1. 字符串转换成包装类:
String str = "123";
Integer numWrapper = Integer.valueOf(str);
  1. 包装类转换成字符串:
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 方法进行拆箱。这样一来,程序员就可以像操作基本数据类型一样操作包装类类型了。

​ 需要注意的是,自动装箱和自动拆箱虽然方便了编程,但是也会带来性能问题。在大量使用时,建议手动进行类型转换,以提高程序性能。

其他注意项

  1. 类型转换:Java中的数据类型有不同的大小和精度,如果将一个大的数据类型转换为一个小的数据类型,会导致数据精度的丢失,这就需要进行类型转换。类型转换可以分为隐式类型转换和显式类型转换两种。
  2. final关键字:final关键字可以用来修饰变量、方法和类。final修饰的变量不能被修改,final修饰的方法不能被覆盖,final修饰的类不能被继承。对于基本数据类型,final修饰的变量必须被初始化,一旦被初始化后就不能再次被修改。
  3. 枚举类型:Java中的枚举类型可以列出一组常量,并为这些常量赋予特定的值。枚举类型可以用来取代常量,使代码更加可读和易于维护。枚举类型也是一种特殊的类,可以有构造函数、方法和字段。
  4. 变量作用域:在Java中,变量有不同的作用域,变量的作用域决定了变量在程序中可以被访问的范围。Java中有四种作用域:类作用域、方法作用域、块作用域和局部作用域。
  5. 常量池:Java中的常量池是指在编译时确定的、存储在.class文件中的常量集合。常量池中可以包含字符串、数字、类名、方法名等常量。Java的数据类型也有对应的常量池,例如Integer类型的常量池中包含了-128~127之间的整数。常量池可以提高程序的运行效率,减少内存的占用。

这些内容也是Java数据类型中比较重要的一些方面,需要开发者在日常的开发中注意。