Java八股文——Java基础「数据类型篇」

八种基本数据类型有哪些

面试官您好,Java的类型系统分为两大类:基本数据类型(Primitive Types)引用数据类型(Reference Types)。其中,基本数据类型是Java语言内置的、最基础的数据单元,共有八种

我通常将这八种基本数据类型分为四大类:

1. 整数类型 (Integral Types)

这类用于表示整数,根据其表示范围的大小,分为:

  • byte: 1字节 (-128 到 127)
  • short: 2字节
  • int: 4字节 (这是最常用的整数类型)
  • long: 8字节

2. 浮点类型 (Floating-Point Types)

这类用于表示带有小数的数值。

  • float: 4字节 (单精度)
  • double: 8字节 (双精度,更常用,精度更高)

3. 字符类型 (Character Type)

  • char: 2字节。它用于表示单个字符,底层存储的是其Unicode编码值。

4. 布尔类型 (Boolean Type)

  • boolean: 它只有两个值:truefalse。它的大小没有被明确规定,通常在JVM中,单个boolean变量可能占1个或4个字节,而在数组中则通常被编码为1个字节。

在实际使用中,有几个非常重要的注意事项:

  • 默认类型

    • 当我们直接写一个整数字面量(如100),它的默认类型是 int。如果要声明一个long类型的常量,必须在末尾加上 Ll (推荐用大写L,避免与数字1混淆),比如 long num = 100L;
    • 当我们直接写一个浮点数字面量(如3.14),它的默认类型是 double。如果要声明一个float类型的常量,必须在末尾加上 Ff,比如 float pi = 3.14F;
  • 包装类 (Wrapper Classes)

    • 为了让这些基本数据类型能够像对象一样被操作(比如存入集合),Java为每一种基本数据类型都提供了一个对应的包装类
    • 大部分包装类的命名就是首字母大写,但有两个特例需要记住:char 对应的是 Characterint 对应的是 Integer
  • char类型的特性

    • char类型在Java中是无符号的,它表示的是Unicode字符集中的码点,范围从 \u0000\uffff (即0到65535),所以它不能表示负数。

掌握这八种基本数据类型及其特性,是进行所有Java编程的基础。

int 和 long 是多少位,多少字节的?

面试官您好,intlong都是Java中用来表示整数的基本数据类型,它们最主要的区别在于占用的内存空间能够表示的数值范围

1. int 类型

  • 位数与字节int 在Java中被定义为一个 32位(bit) 的有符号整数。因为1字节等于8位,所以它占用 4个字节(byte) 的内存空间。
  • 取值范围:作为一个32位的有符号整数,它的取值范围是从 -2³¹2³¹ - 1,这大约是从 -21亿+21亿
  • 应用场景:在日常编程中,int最常用的整数类型。它足以应对大多数场景,比如循环计数、数组索引、以及大多数业务逻辑中的数量表示。

2. long 类型

  • 位数与字节long 则是一个 64位(bit) 的有符号整数,因此它占用 8个字节(byte) 的内存空间。
  • 取值范围:它的取值范围就大得多,是从 -2⁶³2⁶³ - 1。这是一个极其巨大的数值范围,足以应对绝大多数需要大整数的场景。
  • 应用场景:当我们需要处理的整数可能超过21亿时,就必须使用long类型来避免数据溢出。典型的应用场景包括:
    • 表示文件大小,特别是对于GB级别以上的大文件。
    • 数据库中自增主键ID,当表中的记录数可能非常巨大时。
    • 表示时间戳,特别是以毫秒为单位的时间戳(System.currentTimeMillis()的返回值就是long类型)。
    • 在一些分布式系统或算法中,需要用到非常大的数值。

补充一个关键点:字面量

  • 在Java中,我们直接写一个整数字面量(比如 123),它的默认类型是 int
  • 如果我们想声明一个 long 类型的常量,或者赋一个超过 int 范围的值,就必须在数字的末尾加上一个 Ll(官方推荐使用大写L,以避免与数字1混淆)。
    long largeNumber = 3000000000L; // 必须加L,否则会编译错误
    

总结:在选择使用int还是long时,我主要会根据业务数据可能达到的最大值的预估来决定。如果数值不大,就用int,以节约内存;如果存在超过21亿的风险,就果断使用long,以确保数据的正确性。

超过 long 整型的数据应该如何表示?

面试官您好,当我们需要表示的整数超出了long类型的最大范围(即大约922亿亿)时,Java的基本数据类型就无能为力了。在这种情况下,Java标准库提供了一个专门用来处理任意精度整数的强大工具类——java.math.BigInteger

BigInteger之所以能够表示超大整数,主要源于它的几个核心设计:

1. 内部存储:基于int[]数组

  • BigInteger的底层,并不是用一个固定的64位空间来存储数值。相反,它内部使用一个 int类型的数组来表示一个极大的二进制数。数组的每一个元素,都代表了这个大数的一部分。
  • 当数值增大时,这个数组可以动态地扩容。因此,理论上,只要内存足够,BigInteger就可以表示任意大小的整数,没有上限。

2. 对象而非基本类型

  • intlong不同,BigInteger是一个对象。我们需要通过构造函数来创建它的实例。
  • 最常用、也是最安全的构造方式,是使用一个包含数字的字符串作为参数。这可以确保即使初始值就已经超过long的范围,也能被精确地表示。
    BigInteger hugeNumber = new BigInteger("123456789012345678901234567890");
    

3. 通过方法进行运算

  • 由于BigInteger是对象,我们不能直接使用像 +, -, *, / 这样的算术运算符。
  • 相反,BigInteger类提供了一整套丰富的实例方法来进行各种算术运算,例如:
    • add(): 加法
    • subtract(): 减法
    • multiply(): 乘法
    • divide(): 除法
    • 以及 mod(), pow(), gcd() 等各种复杂的数学运算。

4. 不可变性 (Immutability)

  • BigInteger对象是不可变的。这意味着,一旦一个BigInteger对象被创建,它的值就不能被改变。
  • 所有对BigInteger的运算方法(如add, multiply),都不会修改原始对象,而是会返回一个全新的BigInteger对象作为运算结果。
    BigInteger a = new BigInteger("100");
    BigInteger b = a.add(BigInteger.ONE); // a的值仍然是100,b的值是101
    
  • 这种不可变性,使得BigInteger在多线程环境下是线程安全的。

应用场景

  • 密码学:在RSA等非对称加密算法中,经常需要处理几百甚至上千位的极大整数。
  • 科学与金融计算:在一些需要极高精度的计算中,防止任何可能的溢出。
  • 组合数学:计算阶乘、排列组合等,其结果很容易超出long的范围。
  • 唯一ID生成:在某些需要表示超长ID的分布式系统中。

总结

当我们需要处理的整数可能超过long的表示范围时,BigInteger就是Java中标准且唯一的选择。它通过牺牲一部分基本数据类型操作的性能和便利性,换来了表示任意大小整数的能力运算的绝对精确性

long和int可以互转吗 ?

面试官您好,是的,longint这两种类型之间是可以相互转换的。但根据转换的方向不同,其安全性、和实现方式也完全不同。

这主要分为两种情况:自动类型提升强制类型转换

1. 从 int 转换为 long (自动类型提升)

  • 方向:这是从一个小范围的数据类型,向一个大范围的数据类型的转换。

  • 安全性绝对安全。因为long的表示范围(64位)完全覆盖了int的表示范围(32位),所以任何一个int值都可以被long精确地表示,不会发生任何数据丢失或溢出

  • 实现方式:这种转换由Java编译器自动完成,我们无需做任何特殊处理,这被称为隐式类型转换 (Implicit Casting)

  • 示例

    int a = 2_000_000_000;
    long b = a; // 完全合法,编译器自动转换,b的值就是20亿
    

2. 从 long 转换为 int (强制类型转换)

  • 方向:这是从一个大范围的数据类型,向一个小范围的数据类型的转换,也叫“窄化转换”。

  • 安全性有风险,可能不安全。这是因为long可以存储远超int表示范围的数值。

  • 实现方式:Java编译器不会自动进行这种转换。如果我们坚持要转,就必须使用显式的强制类型转换,即在long变量前加上(int)。这个语法本身,就是在提醒开发者:“你必须为这个转换的后果负责”。

  • 转换结果

    • 如果long的实际值在int的范围内 (-21亿 到 +21亿):转换是安全的,结果与原始值相同。
      long c = 100L;
      int d = (in
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xumistore

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值