【Java SE】数据类型、变量、类型转换、运算符以及程序逻辑控制

数据类型、变量、类型转换、运算符以及程序逻辑控制

数据类型

基本数据类型

关键字 字节 范围(十进制) 范围(描述) 包装类 说明 示例
int 4字节 -2,147,483,648 ~ 2,147,483,647 [Integer.MIN_VALUE, Integer.MAX_VALUE] Integer 32位有符号整数,默认整型 int a = 100;
short 2字节 -32,768 ~ 32,767 [Short.MIN_VALUE, Short.MAX_VALUE] Short 16位有符号整数 short s = 1000;
long 8字节 -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 [Long.MIN_VALUE, Long.MAX_VALUE] Long 64位有符号整数,字面值加L long l = 100000L;
byte 1字节 -128 ~ 127 [Byte.MIN_VALUE, Byte.MAX_VALUE] Byte 8位有符号整数 byte b = 100;
double 8字节 ±4.9E-324 ~ ±1.8E+308 约15-16位有效数字 Double 双精度浮点数,默认浮点型 double d = 3.14159; double d2 = 3.14d;
float 4字节 ±1.4E-45 ~ ±3.4E+38 约6-7位有效数字 Float 单精度浮点数,字面值加F float f = 3.14f;
char 2字节 0 ~ 65,535 Unicode: U+0000 ~ U+FFFF Character 16位无符号Unicode字符 char c = 'A'; char c2 = '\u0041';
boolean 未明确规定 true 或 false 只有两个值 Boolean 布尔值,不能与数字相互转换 boolean flag = true; boolean isValid = false;

引用数据类型

类型 关键字/语法 存储内容 默认值 示例
字符串 String Unicode字符序列 null String s = "Hello";
class 对象实例 null Person p = new Person();
接口 interface 实现类的实例 null List<String> list = new ArrayList<>();
数组 [] 同类型元素集合 null int[] arr = {1, 2, 3};
枚举 enum 预定义常量集合 null Day day = Day.MONDAY;
注解 @interface 元数据 null @Override

变量

浮点型要点

int/intdouble/double

java 复制代码
int a = 1;
int b = 2;
System.out.println(a / b);   // 输出 0,不是 0.5

double a = 1.0;
double b = 2.0;
System.out.println(a / b);   // 输出0.5
  • 当两个 int 类型的数进行除法运算时,结果仍然是 int 类型

  • Java 会进行整数除法,直接截断小数部分(不是四舍五入)

  • 当两个 double 类型的数进行除法运算时,结果是 double 类型

  • Java 会进行浮点数除法,保留小数部分

如果想要 int 类型相除得到小数结果,有以下几种方法:

java 复制代码
// 方法1:强制类型转换
System.out.println((double) a / b);  // 输出 0.5

// 方法2:使用浮点数表示
System.out.println(a / 2.0);         // 输出 0.5

// 方法3:乘以 1.0 转换为浮点数
System.out.println(a * 1.0 / b);     // 输出 0.5

浮点数只是近似值

java 复制代码
// 示例1:简单的小数运算
System.out.println(0.1 + 0.2);  // 输出:0.30000000000000004,不是 0.3

// 示例2:十进制小数的二进制表示问题
System.out.println(0.1 + 0.1 + 0.1);  // 输出:0.30000000000000004

// 示例3:大数和小数的运算
double large = 1.0e20;
double small = 1.0;
System.out.println(large + small - large);  // 输出:0.0(精度丢失)
  • 十进制小数(如 0.1)在二进制中是循环小数(类似 1/3 在十进制中是 0.333...)

什么时候需要特别注意?

java 复制代码
// 避免直接比较浮点数是否相等
double a = 0.1 + 0.2;
double b = 0.3;
System.out.println(a == b);  // false!错误方式

// 正确的比较方式:使用容差范围
double epsilon = 1e-10;
System.out.println(Math.abs(a - b) < epsilon);  // true

需要精确计算的场景:

java 复制代码
// 使用 BigDecimal(大数运算)
import java.math.BigDecimal;

BigDecimal d1 = new BigDecimal("0.1");
BigDecimal d2 = new BigDecimal("0.2");
System.out.println(d1.add(d2));  // 输出精确的 0.3

// 但要注意构造函数的区别
BigDecimal wrong = new BigDecimal(0.1);  // 已经是不精确的 double
BigDecimal right = new BigDecimal("0.1"); // 使用字符串构造

字符型要点

字符型编码

java 复制代码
char ch = 'A';
char ch2 = '中';  // 中文字符
char ch3 = '😊';   // 表情符号(这是一个补充字符)

System.out.println("char 大小(字节): " + Character.BYTES);  // 输出 2
System.out.println("char 位数: " + Character.SIZE);            // 输出 16
  • Java 使用 UTF-16 编码表示字符(早期设计时称为 "Unicode 字符")
  • 一个 char 可以表示 Unicode 基本多文种平面(BMP)中的字符,范围是 U+0000 到 U+FFFF
  • 这需要 16 位,即 2 个字节

布尔型要点

boolean 的严格类型检查

  • Java 的 booleanint 是互不兼容的类型
  • 不能 用 1 表示 true,0 表示 false
  • 不能 在条件语句中使用非布尔表达式
java 复制代码
// ========== 错误用法(编译错误)==========
// 1. 不能用数字赋值给boolean
boolean b1 = 1;        // 错误!不能将int转换为boolean
boolean b2 = 0;        // 错误!

// 2. 条件语句必须用boolean
int x = 10;
if (x) {               // 错误!条件必须是boolean类型
    System.out.println("x is true");
}

// 3. 不能将boolean转换为int
boolean flag = true;
int num = flag;        // 错误!不能将boolean转换为int
int num2 = flag ? 1 : 0;  // 这是正确的(三元表达式返回int)

// ========== 正确用法 ==========
// 1. 只能使用true/false
boolean b3 = true;     // 正确
boolean b4 = false;    // 正确

// 2. 条件必须是boolean表达式
int x = 10;
if (x > 5) {           // 正确:比较表达式返回boolean
    System.out.println("x > 5");
}

// 3. 需要转换时使用显式逻辑
boolean flag = true;
// 将boolean转换为int
int num = flag ? 1 : 0;      // 正确:使用三元运算符
int num2 = flag ? 100 : 200; // 正确:可以指定任意值

// 将int转换为boolean(需要显式比较)
int value = 1;
boolean isTrue = (value != 0);  // 正确:通过比较得到boolean
boolean isOne = (value == 1);   // 正确

类型提升和转换

自动类型提升(隐式)

自动类型转换即:代码不需要经过任何处理,在代码编译时,编译器会自动进行处理。

特点:数据范围小的转为数据范围大的时会自动进行。

复制代码
byte → short → int → long → float → double
          ↑
         char
java 复制代码
// ✅ 正确的自动转换(小→大)
byte b = 10;        // byte范围: -128~127
short s = b;        // byte → short ✓
int i = s;          // short → int ✓
long l = i;         // int → long ✓

// ❌ 错误的转换(大→小,需要强制转换)
// long l2 = 100L;
// int i2 = l2;      // 编译错误:long → int
int i2 = (int)l2;   // 需要强制类型转换
java 复制代码
// 1. int 和 long 运算
int a = 10;
long b = 20L;
long result1 = a + b;  // a自动提升为long

// 2. byte 和 byte 运算
byte x = 10;
byte y = 20;
int result2 = x + y;   // byte运算自动提升为int
// 问题:下面的输出是什么?
byte x1 = 10;
byte y1 = 20;
// byte c1 = x1 + y1;  // 编译错误
byte c1 = (byte)(x1 + y1);  // ✅ 需要强转

// 3. float 和 double 运算
float f = 3.14F;
double d = 2.5;
double result3 = f + d; // f自动提升为double

强制类型转换(显式)

特点:数据范围大的到数据范围小的

java 复制代码
// 示例1:整数截断
int num = 300;
byte b = (byte)num;  // 结果为44,发生溢出

// 示例2:浮点数转整数
double d = 3.99;
int i = (int)d;      // 结果为3,小数部分被截断

// 示例3:大整数转小整数
long bigNum = 1234567890123L;
int smallNum = (int)bigNum;  // 可能得到意外结果
java 复制代码
boolean flag = true;
// int num = flag;      // ❌ 编译错误,不能转换
// flag = (boolean)1;   // ❌ 编译错误,不能转换

// 只有数值类型之间可以相互转换
// 引用类型的转换需要继承关系

字符串转换方法

目标类型 转换方法 示例
Stringint Integer.parseInt() int i = Integer.parseInt("123");
Stringdouble Double.parseDouble() double d = Double.parseDouble("3.14");
Stringboolean Boolean.parseBoolean() boolean b = Boolean.parseBoolean("true");
任意 → String String.valueOf()String str = num + ""; String s = String.valueOf(123);

运算符

运算符完整总结表

类别 运算符 名称 说明 示例 结果 优先级 结合性
算术运算符 + 加法 数值相加或字符串连接 5 + 3 "Hello" + "World" 8 "HelloWorld" 4 左→右
- 减法 数值相减 10 - 4 6 4 左→右
* 乘法 数值相乘 3 * 4 12 3 左→右
/ 除法 整数除法或浮点数除法 10 / 3 10.0 / 3 3 3.333... 3 左→右
% 取模 求余数 10 % 3 1 3 左→右
++ 自增 前/后自增 a=5; b=++a a=5; b=a++ a=6, b=6 a=6, b=5 2 右→左
-- 自减 前/后自减 a=5; b=--a a=5; b=a-- a=4, b=4 a=4, b=5 2 右→左
关系运算符 > 大于 比较大小 5 > 3 true 6 左→右
< 小于 比较大小 3 < 5 true 6 左→右
>= 大于等于 比较大小 5 >= 5 true 6 左→右
<= 小于等于 比较大小 3 <= 5 true 6 左→右
== 等于 值相等判断 5 == 5 true 7 左→右
!= 不等于 值不相等判断 5 != 3 true 7 左→右
逻辑运算符 && 逻辑与 短路与,全真为真 true && false false 11 左→右
` ` 逻辑或 短路或,一真即真 `true
! 逻辑非 取反 !true false 2 右→左
& 逻辑与 非短路与 true & false false 8 左→右
` ` 逻辑或 非短路或 `true false` true
^ 逻辑异或 相同为假,不同为真 true ^ false true 9 左→右
位运算符 & 按位与 二进制位与运算 5 & 3 (101 & 011) 1 (001) 8 左→右
` ` 按位或 二进制位或运算 `5 3` (101 | 011) 7 (111)
^ 按位异或 二进制位异或 5 ^ 3 (101 ^ 011) 6 (110) 9 左→右
~ 按位取反 二进制位取反 ~5 -6 2 右→左
<< 左移位 左移指定位数 5 << 1 (101左移1位) 10 (1010) 5 左→右
>> 右移位 带符号右移 -5 >> 1 -3 5 左→右
>>> 无符号右移 高位补0右移 -5 >>> 1 2147483645 5 左→右
赋值运算符 = 赋值 将右值赋给左值 a = 5 a = 5 14 右→左
+= 加赋值 a = a + b a += 3 a = a + 3 14 右→左
-= 减赋值 a = a - b a -= 3 a = a - 3 14 右→左
*= 乘赋值 a = a * b a *= 3 a = a * 3 14 右→左
/= 除赋值 a = a / b a /= 3 a = a / 3 14 右→左
%= 取模赋值 a = a % b a %= 3 a = a % 3 14 右→左
&= 与赋值 a = a & b a &= 3 a = a & 3 14 右→左
` =` 或赋值 `a = a b` `a = 3`
^= 异或赋值 a = a ^ b a ^= 3 a = a ^ 3 14 右→左
<<= 左移赋值 a = a << b a <<= 1 a = a << 1 14 右→左
>>= 右移赋值 a = a >> b a >>= 1 a = a >> 1 14 右→左
>>>= 无符号右移赋值 a = a >>> b a >>>= 1 a = a >>> 1 14 右→左
三元运算符 ? : 条件运算符 根据条件选择值 a > b ? a : b 较大值 13 右→左
类型运算符 instanceof 实例判断 判断对象类型 obj instanceof String true/false 6 左→右
其他 () 括号 改变运算顺序 (a + b) * c 先加后乘 1 左→右
[] 下标 数组访问 arr[0] 数组第一个元素 1 左→右
. 成员访问 访问对象成员 obj.method() 调用方法 1 左→右

优先级从高到低总结(数字越小优先级越高):

  1. () [] .
  2. ! ~ ++ --(一元)
  3. * / %
  4. + -
  5. << >> >>>
  6. < <= > >= instanceof
  7. == !=
  8. &
  9. ^
  10. |
  11. &&
  12. ||
  13. ? :
  14. = += -= *= /= %= &= |= ^= <<= >>= >>>=

程序逻辑控制

顺序结构

分支结构

类型 语法结构 适用场景 特点 执行流程 注意事项
if单分支 if (条件表达式) { // 语句块} 单一条件判断 条件为true时执行代码块 检查条件 → true执行 → 结束 条件必须是布尔表达式
if-else双分支 if (条件表达式) { // 语句块1} else { // 语句块2} 二选一执行 两个互斥的分支 检查条件 → true执行块1 / false执行块2 else必须与if配对使用
if-else if-else多分支 if (条件1) { // 语句块1} else if (条件2) { // 语句块2} else { // 语句块3} 多条件判断 多个互斥条件,顺序检查 按顺序检查条件 → 第一个true执行对应块 → 结束 条件顺序影响结果
嵌套if if (条件1) { if (条件2) { // 语句块<br> }} 复杂条件判断 在if内部再包含if 外层条件通过 → 检查内层条件 → 执行 避免嵌套过深(不超过3层)
switch-case switch (表达式) { case 值1: // 语句块1 break; case 值2: // 语句块2 break; default: // 默认语句块} 等值比较的多分支 基于表达式的值选择分支 计算表达式 → 匹配case → 执行对应块 → break跳出 1. 表达式类型有限制 2. 注意case穿透 3. 必须有break
switch-case(无break) switch (表达式) { case 值1: case 值2: // 共享语句块 break;} 多个值共享相同逻辑 利用case穿透特性 匹配任一case → 向下执行直到break 有意使用case穿透时,要写清楚注释
三元运算符 条件 ? 表达式1 : 表达式2 简单的二选一赋值 if-else的简写形式 计算条件 → true返回表达式1 / false返回表达式2 1. 必须有返回值 2. 表达式类型要兼容

switch表达式支持的类型

数据类型 支持版本 示例
byte 所有版本 switch (b)
short 所有版本 switch (s)
int 所有版本 switch (i)
char 所有版本 switch (ch)
String Java 7+ switch (str)
enum Java 5+ switch (color)
包装类 Java 5+(自动拆箱) switch (integer)
  • 注意不能是long类型

循环结构

循环结构对比总表

循环类型 语法格式 执行顺序 特点 适用场景 示例
for循环 for (初始化; 条件; 更新) {<br> // 循环体<br>}<br> 初始化 → 条件判断 → 循环体 → 更新 → 条件判断... 1. 循环次数明确 2. 结构清晰 3. 变量作用域在循环内 已知循环次数 数组/集合遍历 固定次数的操作 for (int i=0; i<5; i++) {<br> System.out.println(i);<br>}<br>
while循环 while (条件表达式) {<br> // 循环体<br>}<br> 条件判断 → 循环体 → 条件判断... 1. 先判断后执行 2. 可能一次都不执行 3. 适合条件复杂的情况 循环次数不确定 条件驱动循环 读取流/用户输入 int i=0;<br>while (i<5) {<br> System.out.println(i);<br> i++;<br>}<br>
do-while循环 do {<br> // 循环体<br>} while (条件表达式);<br> 循环体 → 条件判断 → 循环体... 1. 先执行后判断 2. 至少执行一次 3. 末尾有分号 至少执行一次 输入验证 菜单显示 int i=0;<br>do {<br> System.out.println(i);<br> i++;<br>} while (i<5);<br>
增强for循环 (foreach) for (类型 变量 : 集合/数组) {<br> // 循环体<br>}<br> 遍历集合/数组每个元素 1. 简化遍历语法 2. 只读遍历 3. 不能获取索引 遍历数组/集合 不需要修改元素 不需要索引 int[] arr = {1,2,3};<br>for (int num : arr) {<br> System.out.println(num);<br>}<br>

输入输出

输出到控制台

java 复制代码
System.out.println(msg);            // 输出一个字符串, 带换行
System.out.print(msg);              // 输出一个字符串, 不带换行
System.out.printf(format, msg);     // 格式化输出
转换符 类型 举例 结果
d 十进制整数 ("%d", 100) 100
x 十六进制整数 ("%x", 100) 64
o 八进制整数 ("%o", 100) 144
f 定点浮点数 ("%f", 100f) 100.000000
e 指数浮点数 ("%e", 100f) 1.000000e+02
g 通用浮点数 ("%g", 100f) 100.000
a 十六进制浮点数 ("%a", 100) 0x1.9p6
s 字符串 ("%s", 100) 100
c 字符 ("%c", '1') 1
b 布尔值 ("%b", 100) true
h 散列码 ("%h", 100) 64
% 百分号 ("%.2f%%", 2/7f) 0.29%

从键盘输入

java 复制代码
import java.util.Scanner;  // 需要导入 util 包
 
Scanner sc = new Scanner(System.in);
System.out.println("请输入你的姓名:");
String name = sc.nextLine();
System.out.println("请输入你的年龄:");
int age = sc.nextInt();
System.out.println("请输入你的工资:");
float salary = sc.nextFloat();
System.out.println("你的信息如下:");
System.out.println("姓名: "+name+"\n"+"年龄:"+age+"\n"+"工资:"+salary);
sc.close(); // 注意, 要记得调用关闭方法
java 复制代码
//多个输入,使用 ctrl + z 来结束输入 (Linux / Mac 上使用 ctrl+ d)
Scanner sc = new Scanner(System.in);
int sum = 0;
int num = 0;
while (sc.hasNextInt()) {
    int tmp = sc.nextInt();
    sum += tmp;
    num++;
}
System.out.println("sum = " + sum);
System.out.println("avg = " + sum / num);
sc.close();
相关推荐
闻哥2 小时前
Redis 避坑指南:从命令到主从的全链路踩坑实录
java·数据库·redis·缓存·面试·springboot
Jinkxs2 小时前
基于 Java 的消息队列选型年度总结:RabbitMQ、RocketMQ、Kafka 实战对比
java·kafka·java-rocketmq·java-rabbitmq
独自破碎E2 小时前
JDK版本的区别
java·开发语言
谦宸、墨白3 小时前
从零开始学C++:二叉树进阶
开发语言·数据结构·c++
建群新人小猿3 小时前
陀螺匠企业助手—个人简历
android·大数据·开发语言·前端·数据库
悟空码字3 小时前
SpringBoot深度整合高德地图,构建高性能位置服务
java·springboot·高德地图·编程技术·后端开发
千金裘换酒3 小时前
栈和队列定义及常用语法 LeetCode
java·开发语言
be or not to be4 小时前
JavaScript 对象与原型
开发语言·javascript·ecmascript
0x534 小时前
JAVA|智能无人机平台(二)
java·开发语言·无人机