整型 int
本章定位:int是Java最常用的整数类型,32位有符号二进制补码,取值范围约±21亿。它是整数字面量的默认类型,也是循环计数器、数组索引、商品数量、工号的"标配"。大翔说过:"在飞翔科技,能用int的地方就别用其他整数类型,除非你有特别的理由。"
定义与语法
| 属性 | 说明 |
|---|---|
| 关键字 | int(整型) |
| 位数 | 32 bits(4字节) |
| 表示法 | 有符号二进制补码 |
| 取值范围 | -2147483648 ~ 2147483647(即 -2³¹ ~ 2³¹-1) |
| 默认值 | 0 |
| 包装类 | java.lang.Integer |
| 字面量默认 | 所有整数字面量(如100、0xFF)默认是int |
基本声明
int quantity = 1000; // 商品库存1000件
int empId = 10001; // 工号
int studentCount = 1000; // 全校学生数
int dailyVisits = 10000; // 日门诊量1万
int caloriesBurned = 500; // 消耗500千卡
int cookTime = 1800; // 烹饪30分钟(1800秒)
字面量的多种进制表示(JDK 7+)
int decimal = 8888; // 十进制
int binary = 0b10001010111000; // 二进制(0b前缀,JDK 7+)
int octal = 021270; // 八进制(0前缀)
int hex = 0x22B8; // 十六进制(0x前缀)
int withUnderscore = 8_888; // 下划线分隔(JDK 7+),增强可读性
深度原理:int在JVM中的特殊地位
为什么int是默认类型?
三大原因:
- JVM操作数栈每槽32位:int天然匹配,无需扩展/拆分
- CPU寄存器通常是32/64位:int操作对应一条机器指令,byte/short需要额外的符号扩展指令
- 数组索引必须是int:Java数组长度最大为
Integer.MAX_VALUE(约21亿),这由JVM规范直接限定
int的32位二进制全景
完整代码示例
示例一:飞翔科技工资系统中的int应用
/**
* 飞翔科技 - int 类型演示
* 场景:大翔的工资单,用int处理工号、绩效分、出勤天数等
*/
public class IntSalaryDemo {
public static void main(String[] args) {
// 员工信息
int empId = 10001;
int performanceScore = 100; // 绩效满分100
int attendanceDays = 22; // 出勤天数
int workHours = 176; // 月工作时长(22天×8小时)
// 工资计算(int处理整数部分,float处理金额)
float basicSalary = 8888.00f;
float performanceBonus = 18888.00f;
float dailySalary = basicSalary / attendanceDays;
float hourlyRate = basicSalary / workHours;
// 绩效评级
String grade;
if (performanceScore >= 90) {
grade = "A级(优秀)";
} else if (performanceScore >= 75) {
grade = "B级(良好)";
} else {
grade = "C级(待改进)";
}
float actualSalary = basicSalary + performanceBonus - 2320.00f - 1666.66f;
System.out.println("【飞翔科技 - 工资单】");
System.out.println("工号:" + empId);
System.out.println("绩效分:" + performanceScore + "分 → " + grade);
System.out.println("出勤:" + attendanceDays + "天,工时:" + workHours + "小时");
System.out.println("日薪:¥" + String.format("%.2f", dailySalary));
System.out.println("时薪:¥" + String.format("%.2f", hourlyRate));
System.out.println("实发工资:¥" + String.format("%.2f", actualSalary));
}
}
运行输出:
【飞翔科技 - 工资单】
工号:10001
绩效分:100分 → A级(优秀)
出勤:22天,工时:176小时
日薪:¥404.00
时薪:¥50.50
实发工资:¥23789.34
示例二:int溢出——21亿陷阱
/**
* 飞翔科技 - int 溢出演示
* 场景:小崔用int存公司总资产(1000亿),结果算出来是负数
*/
public class IntOverflowDemo {
public static void main(String[] args) {
int maxInt = Integer.MAX_VALUE;
System.out.println("【int 溢出陷阱】");
System.out.println("Integer.MAX_VALUE = " + maxInt);
System.out.println("MAX_VALUE + 1 = " + (maxInt + 1) + " ← 溢出为负数!");
// 飞翔科技场景:公司资产1000亿,int存不下
// int companyAsset = 100_000_000_000; // 编译错误:integer number too large
long companyAsset = 100_000_000_000L; // ✅ 用long,加L后缀
System.out.println("\n公司总资产(用long存储):¥" + companyAsset);
// int 溢出检查:人口统计
int wrongPopulation = 8_000_000_000; // 编译错误
// long population = 8_000_000_000L; // ✅ 80亿世界人口用long
System.out.println("\n【int 适用场景】");
System.out.println("int 适合存储 ±21亿 以内的整数");
System.out.println("超出此范围必须使用 long(加L后缀)");
}
}
运行输出:
【int 溢出陷阱】
Integer.MAX_VALUE = 2147483647
MAX_VALUE + 1 = -2147483648 ← 溢出为负数!
公司总资产(用long存储):¥100000000000
【int 适用场景】
int 适合存储 ±21亿 以内的整数
超出此范围必须使用 long(加L后缀)
易错场景
反例一:两个int相乘结果超出int范围
// ❌ 危险:两个大int相乘,中间结果溢出后才赋给long
int secondsPerDay = 24 * 60 * 60; // 86400,没问题
int daysPerYear = 365;
long microSecondsPerYear = secondsPerDay * daysPerYear * 1000000L;
// 问题:secondsPerDay * daysPerYear 先以int计算 → 31536000(还能装下)
// 但如果是更大的数会溢出
// ❌ 更典型的反例:
int a = 100000;
int b = 100000;
long result = a * b; // a*b 以int计算 = 1410065408(溢出!),再赋给long
System.out.println(result); // 输出1410065408,而不是10000000000
// ✅ 正确:至少一个操作数是long,整个表达式以long计算
long correctResult = (long) a * b; // 或 1L * a * b
System.out.println(correctResult); // 输出10000000000
反例二:int做除法丢失小数
// ❌ 错误:整数除法 = 整除
int total = 10;
int count = 3;
int average = total / count; // 结果 = 3,而不是3.333...
System.out.println(average); // 输出 3
// ✅ 正确:转为浮点再做除法
double accurateAverage = (double) total / count; // 3.333...
System.out.println(accurateAverage); // 输出 3.3333333333333335
反例三:int存时间戳(毫秒级)可能溢出
// int 最大约21亿,即约24天(毫秒)
// int timestamp = System.currentTimeMillis(); // 编译错误!long不能转int
// ✅ 正确:时间戳必须用 long
long timestamp = System.currentTimeMillis(); // ✅
面试考点
Q1:Java中整数运算的最小单位是什么类型?
是
int。Java语言规范规定:byte、short、char在参与算术运算、位运算、比较运算之前,都会先自动提升为int。运算结果也是int(除非有long或浮点参与)。因此,两个byte相加的结果是int,两个short相加的结果也是int。
Q2:Integer.MAX_VALUE + 1等于多少?
等于
Integer.MIN_VALUE(-2147483648),发生整数溢出回绕。Java的整数溢出不会抛出异常,而是静默回绕到另一端的极值。这与C#的checked上下文不同,Java没有内置的溢出检查机制(JDK 8中可使用Math.addExact()等方法,它们会在溢出时抛出ArithmeticException)。
Q3:JDK 7的0b前缀和下划线分隔符有什么作用?
0b前缀允许直接书写二进制字面量(如0b1010=10),使得位掩码等操作更加直观。下划线分隔符(如1_000_000)纯粹是为了增强代码可读性,编译器会忽略下划线。但下划线不能出现在数字开头、结尾或进制前缀旁边(如0x_FF不合法)。
Q4:为什么int i = 10; i = i / 3;结果是3而不是3.33?
Java的整数除法执行截断取整(向零舍入),直接丢弃小数部分,而不是四舍五入。这是故意设计的,与C/C++保持一致。如果需要精确结果,应转换为浮点:
(double)i / 3。