第02章-Java基础语法
2.1 注释的三种方式
注释是程序员在代码中添加的说明性文字,不会被编译器执行,用于提高代码的可读性。
2.1.1 单行注释
使用//开头,从//开始到本行结束的内容都是注释。
// 这是单行注释
public class CommentDemo {
public static void main(String[] args) {
// 输出一句话
System.out.println("Hello"); // 这也是单行注释
}
}
使用场景:
- 对某一行代码进行简短说明
- 临时注释掉某行代码进行调试
2.1.2 多行注释
使用/* */包裹,可以跨越多行。
/*
* 这是多行注释
* 可以写多行内容
* 用于详细说明
*/
public class CommentDemo {
public static void main(String[] args) {
/*
多行注释也可以写在代码中间
但不推荐这样使用
*/
System.out.println("Hello");
}
}
使用场景:
- 对一段代码进行详细说明
- 临时注释掉多行代码进行调试
注意事项:
- 多行注释不能嵌套使用
- 例如:
/* 外层 /* 内层 */ */会报错
2.1.3 文档注释
使用/** */包裹,可以被javadoc工具提取生成API文档。
/**
* 这是一个演示类
* @author 张三
* @version 1.0
* @since JDK 1.8
*/
public class CommentDemo {
/**
* 程序入口方法
* @param args 命令行参数
*/
public static void main(String[] args) {
System.out.println("Hello");
}
/**
* 计算两个数的和
* @param a 第一个加数
* @param b 第二个加数
* @return 两数之和
*/
public int add(int a, int b) {
return a + b;
}
}
常用文档注释标签:
@author:作者@version:版本号@since:最早使用的JDK版本@param:参数说明@return:返回值说明@throws:可能抛出的异常@deprecated:标记过时的方法
生成文档:
# 生成API文档
javadoc -d doc -encoding UTF-8 CommentDemo.java
2.1.4 注释的最佳实践
好的注释:
// 计算圆的面积:π * r²
double area = Math.PI * radius * radius;
// 检查用户是否有管理员权限
if (user.hasRole("ADMIN")) {
// ...
}
不好的注释(废话注释):
// 定义变量a
int a = 10;
// 调用方法
method();
注释原则:
- 注释应该解释"为什么",而不是"是什么"
- 代码能自解释的地方不需要注释
- 复杂逻辑、算法需要详细注释
- 公共API必须有文档注释
2.2 标识符命名规则与规范
标识符是程序员为类、变量、方法等起的名字。
2.2.1 标识符命名规则(硬性要求)
必须遵守的规则,否则编译错误:
-
由字母、数字、下划线(_)、美元符号($)组成
int age; // ✅ 正确 int user_name; // ✅ 正确 int $price; // ✅ 正确 int user-name; // ❌ 错误:不能包含- int user#name; // ❌ 错误:不能包含# -
不能以数字开头
int num1; // ✅ 正确 int 1num; // ❌ 错误:不能以数字开头 int _123; // ✅ 正确 -
不能使用Java关键字
int age; // ✅ 正确 int public; // ❌ 错误:public是关键字 int class; // ❌ 错误:class是关键字 -
区分大小写
int age; int Age; // 这是两个不同的变量 int AGE; // 这也是不同的变量
2.2.2 标识符命名规范(软性建议)
推荐遵守的规范,提高代码可读性:
1. 类名:大驼峰命名法(UpperCamelCase)
public class Student { } // ✅ 推荐
public class StudentInfo { } // ✅ 推荐
public class student { } // ❌ 不推荐
public class student_info { } // ❌ 不推荐
2. 方法名和变量名:小驼峰命名法(lowerCamelCase)
int age; // ✅ 推荐
int studentAge; // ✅ 推荐
String userName; // ✅ 推荐
int StudentAge; // ❌ 不推荐
int student_age; // ❌ 不推荐
3. 常量名:全大写,下划线分隔
public static final double PI = 3.14159; // ✅ 推荐
public static final int MAX_VALUE = 100; // ✅ 推荐
public static final String DEFAULT_USER_NAME = "admin"; // ✅ 推荐
public static final int maxValue = 100; // ❌ 不推荐
4. 包名:全小写,用点分隔
package com.company.project; // ✅ 推荐
package com.mycompany.myproject; // ✅ 推荐
package Com.Company.Project; // ❌ 不推荐
package com_company_project; // ❌ 不推荐
2.2.3 命名的见名知意原则
好的命名:
// 学生年龄
int studentAge;
// 用户名
String userName;
// 计算总价
public double calculateTotalPrice() { }
// 检查用户是否登录
public boolean isUserLoggedIn() { }
不好的命名:
int a; // 不知道a代表什么
String s; // 不知道s是什么字符串
public void method1() { } // 不知道方法的作用
2.3 关键字与保留字
2.3.1 Java关键字
关键字是Java语言中被赋予特殊含义的单词,全部小写。
Java关键字列表(共50个):
| 类别 | 关键字 |
|---|---|
| 访问控制 | private protected public |
| 类、方法和变量修饰符 | abstract class extends final implements interface native new static strictfp synchronized transient volatile |
| 程序控制 | break continue return do while if else for instanceof switch case default |
| 错误处理 | try catch finally throw throws |
| 包相关 | import package |
| 基本类型 | boolean byte char double float int long short |
| 变量引用 | super this void |
| 保留字 | goto const |
特殊关键字:
true、false、null:不是关键字,但也不能作为标识符
2.3.2 保留字
保留字是Java保留但未使用的关键字:
goto:保留字,但未使用const:保留字,但未使用(使用final代替)
注意: 虽然这两个词未使用,但也不能作为标识符。
2.4 八种基本数据类型
Java是强类型语言,每个变量必须声明类型。数据类型分为基本数据类型和引用数据类型。
2.4.1 基本数据类型概览
| 数据类型 | 关键字 | 占用字节 | 取值范围 | 默认值 |
|---|---|---|---|---|
| 字节型 | byte |
1 | -128 ~ 127 | 0 |
| 短整型 | short |
2 | -32,768 ~ 32,767 | 0 |
| 整型 | int |
4 | -2³¹ ~ 2³¹-1 | 0 |
| 长整型 | long |
8 | -2⁶³ ~ 2⁶³-1 | 0L |
| 单精度浮点型 | float |
4 | ±3.4E+38 | 0.0f |
| 双精度浮点型 | double |
8 | ±1.7E+308 | 0.0d |
| 字符型 | char |
2 | 0 ~ 65535 (Unicode) | ‘\u0000’ |
| 布尔型 | boolean |
1 | true、false | false |
2.4.2 整数类型
1. byte(字节型)
byte age = 20;
byte temperature = -10;
byte maxByte = 127; // 最大值
byte minByte = -128; // 最小值
// byte overflow = 128; // ❌ 超出范围,编译错误
使用场景: 节省内存空间,如读取文件、网络传输
2. short(短整型)
short year = 2024;
short population = 30000;
short maxShort = 32767; // 最大值
short minShort = -32768; // 最小值
使用场景: 较少使用,int已经够用
3. int(整型)- 最常用
int age = 20;
int salary = 10000;
int population = 14000000;
int maxInt = 2147483647; // Integer.MAX_VALUE
int minInt = -2147483648; // Integer.MIN_VALUE
使用场景: 整数运算的首选类型
整数溢出问题:
// 正溢出示例
int max = 2147483647; // int最大值
int overflow1 = max + 1;
System.out.println(overflow1); // 输出:-2147483648(溢出变成最小值)
// 负溢出示例
int min = -2147483648; // int最小值
int overflow2 = min - 1;
System.out.println(overflow2); // 输出:2147483647(溢出变成最大值)
// 乘法溢出示例
int a = 100000;
int b = 50000;
int result = a * b; // 5000000000,超出int范围
System.out.println(result); // 输出:705032704(溢出)
// 解决方案1:使用long
long result2 = (long) a * b; // 先将a转为long,再相乘
System.out.println(result2); // 输出:5000000000
// 解决方案2:使用Math.addExact等方法(Java 8+)
try {
int safeResult = Math.addExact(max, 1); // 抛出ArithmeticException
} catch (ArithmeticException e) {
System.out.println("整数溢出!");
}
如何避免溢出:
- 选择合适的数据类型(需要大数用long)
- 运算前进行范围检查
- 使用Math.addExact、Math.multiplyExact等安全方法
- 对于金融计算,使用BigDecimal或BigInteger
4. long(长整型)
long distance = 384400000L; // 地球到月球的距离,需要加L后缀
long population = 8000000000L; // 全球人口
long maxLong = 9223372036854775807L; // Long.MAX_VALUE
// long num = 10000000000; // ❌ 错误:超出int范围,需要加L
long num = 10000000000L; // ✅ 正确
注意: long类型的数字后面必须加L或l(推荐大写L,因为小写l容易与数字1混淆)
2.4.3 浮点类型
1. float(单精度)
float price = 19.99f; // 必须加f或F后缀
float pi = 3.14f;
float weight = 65.5f;
// float num = 3.14; // ❌ 错误:默认是double,需要加f
精度: 约6-7位有效数字
2. double(双精度)- 浮点数的默认类型
double price = 19.99; // 默认就是double,可以不加d
double pi = 3.14159265359;
double weight = 65.5d; // 也可以加d或D后缀
// 科学计数法
double num1 = 3.14e2; // 314.0
double num2 = 3.14e-2; // 0.0314
精度: 约15-16位有效数字
浮点数精度问题:
System.out.println(0.1 + 0.2); // 输出:0.30000000000000004
System.out.println(0.3 == 0.1 + 0.2); // false
// 原因:浮点数采用二进制存储,无法精确表示某些十进制小数
// 解决方案:使用BigDecimal类进行精确计算
BigDecimal精确计算示例:
import java.math.BigDecimal;
import java.math.RoundingMode;
public class BigDecimalDemo {
public static void main(String[] args) {
// ❌ 错误方式:直接使用double计算
double price1 = 0.1;
double price2 = 0.2;
System.out.println("double计算:0.1 + 0.2 = " + (price1 + price2));
// 输出:0.30000000000000004
// ✅ 正确方式:使用BigDecimal
// 方式1:使用字符串构造(推荐)
BigDecimal bd1 = new BigDecimal("0.1");
BigDecimal bd2 = new BigDecimal("0.2");
BigDecimal sum = bd1.add(bd2);
System.out.println("BigDecimal计算:0.1 + 0.2 = " + sum);
// 输出:0.3
// 方式2:使用valueOf(推荐)
BigDecimal bd3 = BigDecimal.valueOf(0.1);
BigDecimal bd4 = BigDecimal.valueOf(0.2);
System.out.println("valueOf计算:" + bd3.add(bd4));
// ❌ 方式3:使用double构造(不推荐,仍有精度问题)
BigDecimal bd5 = new BigDecimal(0.1); // 不推荐
System.out.println("double构造:" + bd5);
// 输出:0.1000000000000000055511151231257827021181583404541015625
// BigDecimal四则运算
BigDecimal a = new BigDecimal("10.5");
BigDecimal b = new BigDecimal("3.2");
// 加法
BigDecimal addResult = a.add(b);
System.out.println("加法:" + a + " + " + b + " = " + addResult);
// 减法
BigDecimal subtractResult = a.subtract(b);
System.out.println("减法:" + a + " - " + b + " = " + subtractResult);
// 乘法
BigDecimal multiplyResult = a.multiply(b);
System.out.println("乘法:" + a + " × " + b + " = " + multiplyResult);
// 除法(需要指定精度和舍入模式)
BigDecimal divideResult = a.divide(b, 2, RoundingMode.HALF_UP);
System.out.println("除法:" + a + " ÷ " + b + " = " + divideResult);
// 实际应用:计算商品总价
BigDecimal price = new BigDecimal("19.99"); // 单价
BigDecimal quantity = new BigDecimal("3"); // 数量
BigDecimal total = price.multiply(quantity);
System.out.println("总价:" + total); // 59.97
}
}
BigDecimal常用方法:
| 方法 | 说明 | 示例 |
|---|---|---|
add(BigDecimal) |
加法 | a.add(b) |
subtract(BigDecimal) |
减法 | a.subtract(b) |
multiply(BigDecimal) |
乘法 | a.multiply(b) |
divide(BigDecimal, 精度, 舍入模式) |
除法 | a.divide(b, 2, RoundingMode.HALF_UP) |
compareTo(BigDecimal) |
比较大小 | a.compareTo(b) |
doubleValue() |
转为double | bd.doubleValue() |
intValue() |
转为int | bd.intValue() |
舍入模式(RoundingMode):
| 舍入模式 | 说明 | 示例 |
|---|---|---|
HALF_UP |
四舍五入 | 2.5 → 3, 2.4 → 2 |
HALF_DOWN |
五舍六入 | 2.5 → 2, 2.6 → 3 |
UP |
向远离零的方向舍入 | 2.1 → 3, -2.1 → -3 |
DOWN |
向零方向舍入(截断) | 2.9 → 2, -2.9 → -2 |
CEILING |
向正无穷方向舍入 | 2.1 → 3, -2.9 → -2 |
FLOOR |
向负无穷方向舍入 | 2.9 → 2, -2.1 → -3 |
何时使用BigDecimal:
- ✅ 金融计算(价格、利率、汇率)
- ✅ 需要精确小数的场景
- ✅ 科学计算
- ❌ 性能要求极高的场景(BigDecimal比double慢)
- ❌ 整数运算(直接用int或long)
2.4.4 字符类型
char(字符型)
char gender = '男'; // 单引号,只能存一个字符
char letter = 'A';
char digit = '9';
char symbol = '$';
// Unicode编码
char ch1 = '\u0041'; // 'A'的Unicode编码
char ch2 = 65; // 直接使用ASCII码值,输出'A'
// 特殊字符(转义字符)
char tab = '\t'; // 制表符
char newline = '\n'; // 换行符
char backslash = '\\'; // 反斜杠
char quote = '\''; // 单引号
常用转义字符:
| 转义字符 | 含义 |
|---|---|
\n |
换行 |
\t |
制表符(Tab) |
\r |
回车 |
\\ |
反斜杠 |
\' |
单引号 |
\" |
双引号 |
注意事项:
char ch1 = 'A'; // ✅ 正确
char ch2 = "A"; // ❌ 错误:双引号是字符串
char ch3 = 'AB'; // ❌ 错误:只能存一个字符
char ch4 = ''; // ❌ 错误:必须有字符
2.4.5 布尔类型
boolean(布尔型)
boolean isStudent = true;
boolean isMarried = false;
boolean flag = 10 > 5; // true
// 注意:Java中的boolean不能用0和1表示
boolean b1 = true; // ✅ 正确
// boolean b2 = 1; // ❌ 错误:不能用数字
使用场景:
- 条件判断
- 循环控制
- 标志位
2.4.6 基本类型的选择建议
// 整数优先使用int
int age = 20;
// 小数优先使用double
double price = 19.99;
// 需要超大整数时使用long
long distance = 384400000L;
// 需要节省空间时使用byte(如数组)
byte[] data = new byte[1024];
// 字符使用char
char grade = 'A';
// 条件判断使用boolean
boolean flag = true;
2.5 变量的声明、初始化和使用
2.5.1 什么是变量
变量是内存中的一块存储空间,用于存储数据。可以理解为一个"容器"。
变量的三要素:
- 数据类型
- 变量名
- 变量值
2.5.2 变量的声明
语法格式:
数据类型 变量名;
示例:
int age; // 声明一个整型变量
double price; // 声明一个双精度浮点型变量
String name; // 声明一个字符串变量
2.5.3 变量的初始化
1. 声明时初始化
int age = 20;
double price = 19.99;
String name = "张三";
2. 先声明后赋值
int age;
age = 20; // 赋值
double price;
price = 19.99;
3. 同时声明多个变量
// 声明多个同类型变量
int a, b, c;
a = 10;
b = 20;
c = 30;
// 声明并初始化多个变量
int x = 10, y = 20, z = 30;
2.5.4 变量的使用
public class VariableDemo {
public static void main(String[] args) {
// 声明并初始化变量
int age = 20;
String name = "张三";
double salary = 5000.0;
// 使用变量
System.out.println("姓名:" + name);
System.out.println("年龄:" + age);
System.out.println("工资:" + salary);
// 修改变量的值
age = 21;
salary = 6000.0;
System.out.println("一年后:");
System.out.println("年龄:" + age);
System.out.println("工资:" + salary);
}
}
2.5.5 变量的使用规则
1. 变量必须先声明后使用
System.out.println(age); // ❌ 错误:age未声明
int age = 20;
System.out.println(age); // ✅ 正确
2. 变量必须初始化后才能使用
int age;
System.out.println(age); // ❌ 错误:age未初始化
int num = 10;
System.out.println(num); // ✅ 正确
3. 变量有作用域
作用域定义: 变量的作用域是指变量可以被访问的代码范围。
基本规则: 变量从声明位置开始,到所在代码块结束。
示例1:代码块作用域
{
int age = 20;
System.out.println(age); // ✅ 正确
}
System.out.println(age); // ❌ 错误:age的作用域已结束
示例2:方法作用域
public class ScopeDemo {
public static void main(String[] args) {
int a = 10; // main方法中的局部变量
if (a > 5) {
int b = 20; // if代码块中的局部变量
System.out.println(a); // ✅ 可以访问a
System.out.println(b); // ✅ 可以访问b
}
System.out.println(a); // ✅ 可以访问a
// System.out.println(b); // ❌ 错误:b的作用域已结束
}
}
示例3:循环作用域
// for循环中声明的变量
for (int i = 0; i < 5; i++) {
System.out.println(i); // ✅ 可以访问i
}
// System.out.println(i); // ❌ 错误:i的作用域已结束
// 如果需要在循环外使用,需要在外部声明
int j;
for (j = 0; j < 5; j++) {
System.out.println(j);
}
System.out.println(j); // ✅ 可以访问j,值为5
示例4:内层可以访问外层,外层不能访问内层
public static void main(String[] args) {
int outer = 10; // 外层变量
{
int inner = 20; // 内层变量
System.out.println(outer); // ✅ 内层可以访问外层变量
System.out.println(inner); // ✅ 可以访问自己的变量
}
System.out.println(outer); // ✅ 可以访问
// System.out.println(inner); // ❌ 外层不能访问内层变量
}
示例5:不同作用域可以有同名变量(但不推荐)
public static void method1() {
int num = 10;
System.out.println(num); // 10
}
public static void method2() {
int num = 20; // ✅ 正确:不同方法中可以有同名变量
System.out.println(num); // 20
}
作用域总结:
- ✅ 变量只在声明它的代码块
{}内有效 - ✅ 内层代码块可以访问外层代码块的变量
- ❌ 外层代码块不能访问内层代码块的变量
- ❌ 同一作用域不能声明同名变量
- ✅ 不同作用域可以声明同名变量(但不推荐,容易混淆)
4. 同一作用域内变量名不能重复
int age = 20;
int age = 30; // ❌ 错误:变量名重复
int num1 = 10;
double num1 = 10.5; // ❌ 错误:变量名重复(即使类型不同)
5. 变量可以重新赋值,但类型不能改变
int age = 20;
age = 30; // ✅ 正确:同类型赋值
age = 3.14; // ❌ 错误:类型不匹配
2.5.6 变量的分类
按数据类型分类:
- 基本数据类型变量:
int、double、char等 - 引用数据类型变量:
String、数组、对象等
按声明位置分类:
- 局部变量:在方法内部声明的变量
- 成员变量:在类中、方法外声明的变量(后续章节详解)
2.6 常量的定义
2.6.1 什么是常量
常量是值不能改变的量,一旦赋值后就不能修改。
2.6.2 字面量常量
直接写在代码中的固定值:
10 // 整数常量
3.14 // 浮点数常量
'A' // 字符常量
"Hello" // 字符串常量
true // 布尔常量
2.6.3 final常量
使用final关键字声明:
final double PI = 3.14159;
final int MAX_AGE = 150;
final String APP_NAME = "学生管理系统";
// 尝试修改常量会报错
PI = 3.14; // ❌ 错误:不能给final变量赋值
命名规范:
- 常量名通常全部大写
- 多个单词用下划线分隔
示例程序:
public class ConstantDemo {
public static void main(String[] args) {
// 定义常量
final double PI = 3.14159;
final int DAYS_OF_WEEK = 7;
// 使用常量
double radius = 5.0;
double area = PI * radius * radius;
System.out.println("圆的面积:" + area);
System.out.println("一周有 " + DAYS_OF_WEEK + " 天");
}
}
常量的好处:
- 提高代码可读性
- 便于维护(只需修改一处)
- 防止误修改
- 体现程序的意图
2.7 数据类型转换
在Java中,不同数据类型之间可以进行转换。
2.7.1 自动类型转换(隐式转换)
转换规则: 从小范围类型到大范围类型自动转换。
转换路径:
byte → short → int → long → float → double
char →
示例:
// 自动类型转换
byte b = 10;
int i = b; // byte → int,自动转换
System.out.println(i); // 10
int num = 100;
double d = num; // int → double,自动转换
System.out.println(d); // 100.0
char ch = 'A';
int code = ch; // char → int,自动转换
System.out.println(code); // 65('A'的ASCII码)
注意事项:
// 整数字面量默认是int类型
byte b1 = 10; // ✅ 正确:10在byte范围内,编译器自动转换
byte b2 = 128; // ❌ 错误:128超出byte范围
// 小数字面量默认是double类型
float f1 = 3.14; // ❌ 错误:3.14是double类型
float f2 = 3.14f; // ✅ 正确:加f后缀表示float类型
2.7.2 强制类型转换(显式转换)
转换规则: 从大范围类型到小范围类型需要强制转换。
语法格式:
目标类型 变量名 = (目标类型) 值;
示例:
// 强制类型转换
double d = 3.14;
int i = (int) d; // double → int,强制转换
System.out.println(i); // 3(小数部分被截断)
int num = 130;
byte b = (byte) num; // int → byte,强制转换
System.out.println(b); // -126(发生溢出)
long l = 100L;
int i2 = (int) l; // long → int,强制转换
System.out.println(i2); // 100
数据丢失问题:
// 1. 精度丢失
double d1 = 3.14;
int i1 = (int) d1; // 结果:3(小数部分丢失)
// 2. 数据溢出
int num = 130;
byte b = (byte) num; // 结果:-126(超出byte范围,发生溢出)
// 3. 大整数转小整数
long l = 2147483648L; // 超出int最大值
int i2 = (int) l; // 结果:-2147483648(溢出)
2.7.3 表达式中的类型提升
规则1:byte、short、char参与运算时,自动提升为int
byte b1 = 10;
byte b2 = 20;
// byte b3 = b1 + b2; // ❌ 错误:b1 + b2的结果是int类型
int b3 = b1 + b2; // ✅ 正确
规则2:多种类型混合运算时,提升为范围最大的类型
int i = 10;
double d = 3.14;
double result = i + d; // int自动提升为double
System.out.println(result); // 13.14
byte b = 10;
short s = 20;
int i2 = 30;
long l = 40L;
long result2 = b + s + i2 + l; // 所有类型提升为long
2.7.4 字符串与其他类型的转换
1. 任意类型 + 字符串 = 字符串
int age = 20;
String str1 = "年龄:" + age; // "年龄:20"
double price = 19.99;
String str2 = "价格:" + price; // "价格:19.99"
int a = 10, b = 20;
System.out.println("和:" + a + b); // "和:1020"(字符串拼接)
System.out.println("和:" + (a + b)); // "和:30"(先计算再拼接)
2. 字符串转基本类型
String str = "123";
// 字符串转int
int num = Integer.parseInt(str);
// 字符串转double
String price = "19.99";
double d = Double.parseDouble(price);
// 字符串转boolean
String flag = "true";
boolean b = Boolean.parseBoolean(flag);
2.8 算术运算符
2.8.1 基本算术运算符
| 运算符 | 说明 | 示例 | 结果 |
|---|---|---|---|
+ |
加法 | 5 + 3 |
8 |
- |
减法 | 5 - 3 |
2 |
* |
乘法 | 5 * 3 |
15 |
/ |
除法 | 5 / 3 |
1 |
% |
取模(取余) | 5 % 3 |
2 |
示例代码:
int a = 10, b = 3;
System.out.println("a + b = " + (a + b)); // 13
System.out.println("a - b = " + (a - b)); // 7
System.out.println("a * b = " + (a * b)); // 30
System.out.println("a / b = " + (a / b)); // 3(整数除法)
System.out.println("a % b = " + (a % b)); // 1(余数)
2.8.2 除法运算的注意事项
整数除法:
int a = 10, b = 3;
int result1 = a / b; // 3(结果取整)
System.out.println(result1);
// 如果需要小数结果,至少有一个操作数是浮点数
double result2 = (double) a / b; // 3.3333...
double result3 = a / 3.0; // 3.3333...
System.out.println(result2);
System.out.println(result3);
除数为0的情况:
int a = 10;
int b = 0;
// int result = a / b; // ❌ 运行时错误:ArithmeticException: / by zero
// 浮点数除以0
double d1 = 10.0 / 0;
System.out.println(d1); // Infinity(无穷大)
double d2 = -10.0 / 0;
System.out.println(d2); // -Infinity(负无穷大)
double d3 = 0.0 / 0;
System.out.println(d3); // NaN(Not a Number)
2.8.3 取模运算
取模规则: 结果的符号与被除数相同
System.out.println(10 % 3); // 1
System.out.println(-10 % 3); // -1
System.out.println(10 % -3); // 1
System.out.println(-10 % -3); // -1
// 应用场景:判断奇偶数
int num = 15;
if (num % 2 == 0) {
System.out.println(num + "是偶数");
} else {
System.out.println(num + "是奇数");
}
2.8.4 自增自减运算符
| 运算符 | 说明 | 示例 |
|---|---|---|
++ |
自增(加1) | i++ 或 ++i |
-- |
自减(减1) | i-- 或 --i |
前缀和后缀的区别:
1. 前缀(++i, --i):先运算后使用
int a = 10;
int b = ++a; // a先加1变成11,然后赋值给b
System.out.println("a = " + a); // 11
System.out.println("b = " + b); // 11
2. 后缀(i++, i–):先使用后运算
int a = 10;
int b = a++; // 先把a的值10赋给b,然后a再加1
System.out.println("a = " + a); // 11
System.out.println("b = " + b); // 10
复杂示例:
int i = 5;
int j = i++ + ++i;
// 分解步骤:
// 1. i++ → 先使用5,然后i变成6
// 2. ++i → i先变成7,然后使用7
// 3. j = 5 + 7 = 12
System.out.println("i = " + i); // 7
System.out.println("j = " + j); // 12
建议: 初学者尽量避免在一个表达式中多次使用自增自减,容易混淆。
2.8.5 +号的多种用法
// 1. 数值加法
int sum = 10 + 20; // 30
// 2. 字符串拼接
String str = "Hello" + "World"; // "HelloWorld"
// 3. 正号
int num = +10; // 10
// 4. 混合运算
System.out.println("结果:" + 10 + 20); // "结果:1020"(从左向右拼接)
System.out.println("结果:" + (10 + 20)); // "结果:30"(先计算括号内)
System.out.println(10 + 20 + "分"); // "30分"(先加法后拼接)
2.9 赋值运算符
2.9.1 基本赋值运算符
语法: =
int age = 20; // 将20赋值给age
double price = 19.99; // 将19.99赋值给price
String name = "张三"; // 将"张三"赋值给name
2.9.2 复合赋值运算符
| 运算符 | 说明 | 示例 | 等价于 |
|---|---|---|---|
+= |
加后赋值 | a += 3 |
a = a + 3 |
-= |
减后赋值 | a -= 3 |
a = a - 3 |
*= |
乘后赋值 | a *= 3 |
a = a * 3 |
/= |
除后赋值 | a /= 3 |
a = a / 3 |
%= |
取模后赋值 | a %= 3 |
a = a % 3 |
示例代码:
int a = 10;
a += 5; // a = a + 5; → a = 15
a -= 3; // a = a - 3; → a = 12
a *= 2; // a = a * 2; → a = 24
a /= 4; // a = a / 4; → a = 6
a %= 5; // a = a % 5; → a = 1
System.out.println(a); // 1
复合赋值运算符的特点:
byte b = 10;
// b = b + 5; // ❌ 错误:b + 5是int类型,不能赋值给byte
b += 5; // ✅ 正确:复合赋值运算符会自动强制类型转换
2.10 比较运算符
比较运算符用于比较两个值的大小关系,结果是boolean类型(true或false)。
2.10.1 比较运算符列表
| 运算符 | 说明 | 示例 | 结果 |
|---|---|---|---|
== |
等于 | 5 == 3 |
false |
!= |
不等于 | 5 != 3 |
true |
> |
大于 | 5 > 3 |
true |
< |
小于 | 5 < 3 |
false |
>= |
大于等于 | 5 >= 5 |
true |
<= |
小于等于 | 3 <= 5 |
true |
2.10.2 示例代码
int a = 10, b = 20;
System.out.println(a == b); // false
System.out.println(a != b); // true
System.out.println(a > b); // false
System.out.println(a < b); // true
System.out.println(a >= 10); // true
System.out.println(a <= 10); // true
2.10.3 注意事项
1. 区分 == 和 =
int a = 10;
// if (a = 20) { } // ❌ 错误:赋值语句,不是比较
if (a == 20) { } // ✅ 正确:比较运算
2. 浮点数的比较
double d1 = 0.1 + 0.2;
double d2 = 0.3;
System.out.println(d1 == d2); // false(精度问题)
System.out.println(d1); // 0.30000000000000004
// 浮点数比较应该使用误差范围
double epsilon = 0.0000001;
if (Math.abs(d1 - d2) < epsilon) {
System.out.println("相等");
}
3. 字符的比较
char ch1 = 'A'; // ASCII码:65
char ch2 = 'B'; // ASCII码:66
System.out.println(ch1 < ch2); // true(比较ASCII码值)
System.out.println(ch1 == 65); // true
2.11 逻辑运算符
逻辑运算符用于连接多个boolean表达式,结果也是boolean类型。
2.11.1 逻辑运算符列表
| 运算符 | 说明 | 示例 | 说明 |
|---|---|---|---|
& |
逻辑与 | a & b |
两个都为true,结果才为true |
| ` | ` | 逻辑或 | `a |
^ |
逻辑异或 | a ^ b |
两个不同,结果为true |
! |
逻辑非 | !a |
取反 |
&& |
短路与 | a && b |
同&,但有短路效果 |
| ` | ` | 短路或 |
2.11.2 逻辑与(&)
真值表:
| a | b | a & b |
|---|---|---|
| true | true | true |
| true | false | false |
| false | true | false |
| false | false | false |
示例:
int age = 25;
boolean result = age > 18 & age < 60;
System.out.println(result); // true(年龄在18到60之间)
2.11.3 逻辑或(|)
真值表:
| a | b | a | b |
|—|—|-------|
| true | true | true |
| true | false | true |
| false | true | true |
| false | false | false |
示例:
int score = 85;
boolean result = score < 60 | score > 90;
System.out.println(result); // false(成绩在60-90之间)
2.11.4 逻辑异或(^)
规则: 两个布尔值不同时为true,相同时为false
真值表:
| a | b | a ^ b |
|---|---|---|
| true | true | false |
| true | false | true |
| false | true | true |
| false | false | false |
示例:
boolean a = true, b = false;
System.out.println(a ^ b); // true(不同)
System.out.println(a ^ a); // false(相同)
2.11.5 逻辑非(!)
规则: 取反
boolean flag = true;
System.out.println(!flag); // false
System.out.println(!!flag); // true(两次取反)
int age = 20;
System.out.println(!(age > 18)); // false
2.11.6 短路与(&&)和短路或(||)
短路与(&&):
int a = 10, b = 20;
boolean result = a > 5 && b > 30;
// a > 5为true,继续判断b > 30
// b > 30为false,最终结果为false
// 短路效果
int x = 10;
boolean result2 = x < 5 && ++x > 0;
// x < 5为false,后面的++x不会执行(短路)
System.out.println(x); // 10(x没有自增)
短路或(||):
int a = 10, b = 20;
boolean result = a > 5 || b > 30;
// a > 5为true,不再判断b > 30(短路)
// 最终结果为true
// 短路效果
int x = 10;
boolean result2 = x > 5 || ++x > 0;
// x > 5为true,后面的++x不会执行(短路)
System.out.println(x); // 10(x没有自增)
& 和 && 的区别:
int a = 10;
// 使用&
boolean r1 = a < 5 & ++a > 0; // 两个表达式都会执行
System.out.println(a); // 11
int b = 10;
// 使用&&
boolean r2 = b < 5 && ++b > 0; // 第一个为false,第二个不执行(短路)
System.out.println(b); // 10
建议: 一般情况下使用&&和||,效率更高。
2.11.7 逻辑运算符的应用
判断闰年:
int year = 2024;
boolean isLeapYear = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
System.out.println(year + "是闰年:" + isLeapYear);
判断三角形:
int a = 3, b = 4, c = 5;
boolean isTriangle = a + b > c && a + c > b && b + c > a;
System.out.println("能构成三角形:" + isTriangle);
2.12 三元运算符
2.12.1 语法格式
条件表达式 ? 表达式1 : 表达式2
执行逻辑:
- 如果条件表达式为true,结果为表达式1的值
- 如果条件表达式为false,结果为表达式2的值
2.12.2 基本使用
int a = 10, b = 20;
// 获取两个数中的最大值
int max = a > b ? a : b;
System.out.println("最大值:" + max); // 20
// 获取两个数中的最小值
int min = a < b ? a : b;
System.out.println("最小值:" + min); // 10
// 判断奇偶
int num = 15;
String result = num % 2 == 0 ? "偶数" : "奇数";
System.out.println(num + "是" + result); // 15是奇数
2.12.3 嵌套使用
// 三个数求最大值
int a = 10, b = 20, c = 15;
int max = a > b ? (a > c ? a : c) : (b > c ? b : c);
System.out.println("最大值:" + max); // 20
// 等价的if-else写法
int max2;
if (a > b) {
if (a > c) {
max2 = a;
} else {
max2 = c;
}
} else {
if (b > c) {
max2 = b;
} else {
max2 = c;
}
}
注意: 嵌套过多会降低可读性,建议不超过2层。
2.12.4 与if-else的比较
// 使用三元运算符
int age = 20;
String result = age >= 18 ? "成年人" : "未成年人";
// 使用if-else
String result2;
if (age >= 18) {
result2 = "成年人";
} else {
result2 = "未成年人";
}
选择建议:
- 简单的二选一场景:使用三元运算符,代码更简洁
- 复杂的逻辑或多条语句:使用if-else,可读性更好
2.13 位运算符(了解)
位运算符直接对整数的二进制位进行运算。
2.13.1 位运算符列表
| 运算符 | 说明 | 示例 |
|---|---|---|
& |
按位与 | 6 & 3 → 2 |
| ` | ` | 按位或 |
^ |
按位异或 | 6 ^ 3 → 5 |
~ |
按位取反 | ~6 → -7 |
<< |
左移 | 3 << 2 → 12 |
>> |
右移 | 12 >> 2 → 3 |
>>> |
无符号右移 | -1 >>> 1 |
2.13.2 按位与(&)
int a = 6; // 0110
int b = 3; // 0011
int c = a & b; // 0010 → 2
System.out.println(c); // 2
2.13.3 按位或(|)
int a = 6; // 0110
int b = 3; // 0011
int c = a | b; // 0111 → 7
System.out.println(c); // 7
2.13.4 按位异或(^)
int a = 6; // 0110
int b = 3; // 0011
int c = a ^ b; // 0101 → 5
System.out.println(c); // 5
// 有趣的性质:两次异或恢复原值
int x = 10;
int y = x ^ 5; // 10 ^ 5
int z = y ^ 5; // (10 ^ 5) ^ 5 = 10
System.out.println(z); // 10
2.13.5 移位运算符
左移(<<): 乘以2的n次方
int a = 3; // 0011
int b = a << 2; // 1100 → 12(相当于3 * 2² = 12)
System.out.println(b); // 12
右移(>>): 除以2的n次方
int a = 12; // 1100
int b = a >> 2; // 0011 → 3(相当于12 / 2² = 3)
System.out.println(b); // 3
应用场景:
- 性能优化(位运算比乘除法快)
- 权限控制(使用位标志)
- 加密算法
- 底层编程
2.14 运算符优先级
2.14.1 优先级表
| 优先级 | 运算符 | 说明 |
|---|---|---|
| 1 | () [] . |
括号、数组、成员访问 |
| 2 | ! ~ ++ -- + - |
一元运算符 |
| 3 | * / % |
乘除模 |
| 4 | + - |
加减 |
| 5 | << >> >>> |
移位 |
| 6 | < <= > >= instanceof |
关系运算 |
| 7 | == != |
相等性 |
| 8 | & |
按位与 |
| 9 | ^ |
按位异或 |
| 10 | ` | ` |
| 11 | && |
逻辑与 |
| 12 | ` | |
| 13 | ?: |
三元运算符 |
| 14 | = += -= *= /= %= |
赋值运算 |
2.14.2 记忆口诀
括号优先级最高
单目运算符优先于双目
算术 > 关系 > 逻辑 > 赋值
2.14.3 示例
int a = 10, b = 20, c = 30;
// 示例1
int result1 = a + b * c; // 先乘后加
System.out.println(result1); // 10 + 600 = 610
// 示例2
boolean result2 = a > 5 && b < 30 || c == 30;
// 先比较,再逻辑与,最后逻辑或
System.out.println(result2); // true
// 示例3
int result3 = a + b > c ? a : b;
// 先加法,再比较,最后三元运算
System.out.println(result3); // 20
建议: 不确定优先级时,使用括号明确运算顺序,提高代码可读性。
// 不推荐
int result = a + b * c - d / e;
// 推荐
int result = a + (b * c) - (d / e);
2.15 Scanner键盘输入
2.15.1 Scanner类介绍
Scanner是Java提供的用于获取用户输入的类,位于java.util包中。
2.15.2 基本使用步骤
步骤1:导入Scanner类
import java.util.Scanner;
步骤2:创建Scanner对象
Scanner scanner = new Scanner(System.in);
步骤3:调用方法接收输入
int num = scanner.nextInt(); // 接收整数
步骤4:关闭Scanner(可选)
scanner.close();
2.15.3 常用输入方法
| 方法 | 说明 | 示例 |
|---|---|---|
nextInt() |
接收整数 | int num = scanner.nextInt(); |
nextDouble() |
接收小数 | double d = scanner.nextDouble(); |
next() |
接收字符串(遇空格结束) | String str = scanner.next(); |
nextLine() |
接收一行字符串 | String line = scanner.nextLine(); |
nextBoolean() |
接收布尔值 | boolean b = scanner.nextBoolean(); |
2.15.4 完整示例
import java.util.Scanner;
public class ScannerDemo {
public static void main(String[] args) {
// 创建Scanner对象
Scanner scanner = new Scanner(System.in);
// 接收整数
System.out.print("请输入年龄:");
int age = scanner.nextInt();
// 接收小数
System.out.print("请输入身高(米):");
double height = scanner.nextDouble();
// 接收字符串
System.out.print("请输入姓名:");
String name = scanner.next();
// 输出结果
System.out.println("===== 个人信息 =====");
System.out.println("姓名:" + name);
System.out.println("年龄:" + age);
System.out.println("身高:" + height + "米");
// 关闭Scanner
scanner.close();
}
}
2.15.5 next() 和 nextLine() 的区别
next():
- 遇到空格、Tab、回车就结束
- 只能接收一个单词
Scanner scanner = new Scanner(System.in);
System.out.print("请输入:");
String str = scanner.next();
// 输入:Hello World
// 结果:str = "Hello"(只接收到Hello)
nextLine():
- 遇到回车才结束
- 可以接收包含空格的一行文本
Scanner scanner = new Scanner(System.in);
System.out.print("请输入:");
String str = scanner.nextLine();
// 输入:Hello World
// 结果:str = "Hello World"(接收整行)
2.15.6 常见问题
问题1:nextInt()后接nextLine()出现问题
Scanner scanner = new Scanner(System.in);
System.out.print("请输入年龄:");
int age = scanner.nextInt(); // 输入:20回车
System.out.print("请输入姓名:");
String name = scanner.nextLine(); // 直接跳过,没有等待输入!
System.out.println("年龄:" + age);
System.out.println("姓名:" + name); // name为空
原因: nextInt()只读取数字,回车符还在输入缓冲区,nextLine()直接读取了回车符。
解决方案:
Scanner scanner = new Scanner(System.in);
System.out.print("请输入年龄:");
int age = scanner.nextInt();
scanner.nextLine(); // 清除缓冲区的回车符
System.out.print("请输入姓名:");
String name = scanner.nextLine();
System.out.println("年龄:" + age);
System.out.println("姓名:" + name);
问题2:输入类型不匹配
Scanner scanner = new Scanner(System.in);
System.out.print("请输入年龄:");
int age = scanner.nextInt(); // 如果输入abc,会抛出InputMismatchException
解决方案: 使用异常处理或hasNext系列方法验证输入
2.15.7 输入验证(hasNext系列方法)
常用验证方法:
| 方法 | 说明 | 返回值 |
|---|---|---|
hasNext() |
判断是否有输入 | boolean |
hasNextInt() |
判断下一个输入是否为整数 | boolean |
hasNextDouble() |
判断下一个输入是否为小数 | boolean |
hasNextLine() |
判断是否有下一行 | boolean |
安全的输入方式:
import java.util.Scanner;
public class SafeInputDemo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 验证整数输入
System.out.print("请输入年龄:");
if (scanner.hasNextInt()) {
int age = scanner.nextInt();
System.out.println("您的年龄是:" + age);
} else {
System.out.println("输入错误!请输入整数");
scanner.next(); // 清除错误输入
}
// 验证小数输入
System.out.print("请输入价格:");
if (scanner.hasNextDouble()) {
double price = scanner.nextDouble();
System.out.println("价格是:" + price);
} else {
System.out.println("输入错误!请输入数字");
scanner.next(); // 清除错误输入
}
// 循环验证直到输入正确
int validAge = 0;
boolean isValid = false;
while (!isValid) {
System.out.print("请输入年龄(0-150):");
if (scanner.hasNextInt()) {
int age = scanner.nextInt();
if (age >= 0 && age <= 150) {
validAge = age;
isValid = true;
} else {
System.out.println("年龄范围错误!请输入0-150之间的数字");
}
} else {
System.out.println("输入错误!请输入整数");
scanner.next(); // 清除错误输入
}
}
System.out.println("有效年龄:" + validAge);
scanner.close();
}
}
输入验证的最佳实践:
import java.util.Scanner;
public class InputValidationDemo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 封装输入验证方法
int age = getValidInt(scanner, "请输入年龄:", 0, 150);
double height = getValidDouble(scanner, "请输入身高(米):", 0.5, 2.5);
System.out.println("年龄:" + age);
System.out.println("身高:" + height + "米");
scanner.close();
}
/**
* 获取有效的整数输入
*/
public static int getValidInt(Scanner scanner, String prompt, int min, int max) {
int value = 0;
boolean isValid = false;
while (!isValid) {
System.out.print(prompt);
if (scanner.hasNextInt()) {
value = scanner.nextInt();
if (value >= min && value <= max) {
isValid = true;
} else {
System.out.println("输入范围错误!请输入" + min + "-" + max + "之间的整数");
}
} else {
System.out.println("输入错误!请输入整数");
scanner.next(); // 清除错误输入
}
}
return value;
}
/**
* 获取有效的小数输入
*/
public static double getValidDouble(Scanner scanner, String prompt, double min, double max) {
double value = 0;
boolean isValid = false;
while (!isValid) {
System.out.print(prompt);
if (scanner.hasNextDouble()) {
value = scanner.nextDouble();
if (value >= min && value <= max) {
isValid = true;
} else {
System.out.println("输入范围错误!请输入" + min + "-" + max + "之间的数字");
}
} else {
System.out.println("输入错误!请输入数字");
scanner.next(); // 清除错误输入
}
}
return value;
}
}
2.16 常见错误与调试技巧
2.16.1 编译错误(Compile Error)
错误1:变量未声明
System.out.println(age); // ❌ 错误:cannot find symbol
int age = 20;
原因: 使用变量前未声明
解决: 先声明再使用
错误2:变量未初始化
int age;
System.out.println(age); // ❌ 错误:variable age might not have been initialized
原因: 局部变量未初始化就使用
解决: int age = 0; 或在使用前赋值
错误3:类型不匹配
int num = 3.14; // ❌ 错误:incompatible types
原因: 3.14是double类型,不能直接赋值给int
解决: double num = 3.14; 或 int num = (int)3.14;
错误4:分号缺失
int age = 20 // ❌ 错误:';' expected
System.out.println(age);
原因: 每个语句后必须有分号
解决: int age = 20;
错误5:括号不匹配
public class Test {
public static void main(String[] args) {
System.out.println("Hello");
// ❌ 错误:'}' expected(缺少})
}
原因: 括号没有成对出现
解决: 检查所有的 {} () [] 是否成对
错误6:字符串使用单引号
String name = 'Java'; // ❌ 错误:unclosed character literal
原因: 单引号只能用于字符,双引号用于字符串
解决: String name = "Java";
错误7:数组越界(运行时错误)
int[] arr = {1, 2, 3};
System.out.println(arr[3]); // ❌ 错误:ArrayIndexOutOfBoundsException
原因: 数组索引从0开始,arr[3]不存在
解决: System.out.println(arr[2]);
2.16.2 运行时错误(Runtime Error)
错误1:除以零
int a = 10;
int b = 0;
int result = a / b; // ❌ 运行时错误:ArithmeticException: / by zero
解决:
if (b != 0) {
int result = a / b;
} else {
System.out.println("除数不能为0");
}
错误2:数据溢出(无异常,但结果错误)
int max = 2147483647; // int最大值
int overflow = max + 1;
System.out.println(overflow); // 输出:-2147483648(溢出)
解决: 使用更大的数据类型
long max = 2147483647L;
long result = max + 1; // 2147483648
错误3:空指针异常
String str = null;
System.out.println(str.length()); // ❌ NullPointerException
解决:
if (str != null) {
System.out.println(str.length());
}
2.16.3 逻辑错误(Logic Error)
错误1:== 和 = 混淆
int age = 20;
if (age = 18) { // ❌ 错误:应该用==比较
System.out.println("成年");
}
解决: if (age == 18)
错误2:整数除法精度丢失
int a = 10, b = 3;
double result = a / b; // 结果:3.0(不是3.333...)
原因: a / b 是整数除法,结果为3,然后转换为3.0
解决:
double result = (double) a / b; // 3.3333...
// 或
double result = a / 3.0;
错误3:浮点数比较
double d1 = 0.1 + 0.2;
if (d1 == 0.3) { // false(精度问题)
System.out.println("相等");
}
解决: 使用误差范围
double epsilon = 0.0000001;
if (Math.abs(d1 - 0.3) < epsilon) {
System.out.println("相等");
}
错误4:自增运算符混淆
int i = 5;
int a = i++; // a = 5, i = 6
int b = ++i; // i先变7,b = 7
建议: 避免在一个表达式中多次使用自增运算符
2.16.4 调试技巧
技巧1:使用System.out.println()调试
int a = 10, b = 20;
System.out.println("a = " + a); // 打印变量值
System.out.println("b = " + b);
int sum = a + b;
System.out.println("sum = " + sum);
技巧2:使用IDE断点调试
- 在代码行号左侧点击,设置断点(红点)
- 右键 → Debug运行程序
- 程序会在断点处暂停
- 查看变量值、单步执行
技巧3:注释代码排查问题
// System.out.println(method1()); // 暂时注释掉
System.out.println(method2()); // 测试这个方法
技巧4:分段测试
// 复杂计算分步骤测试
int step1 = a + b;
System.out.println("step1 = " + step1);
int step2 = step1 * c;
System.out.println("step2 = " + step2);
int result = step2 / d;
System.out.println("result = " + result);
技巧5:查看错误信息
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Test.main(Test.java:5)
- 错误类型:ArithmeticException
- 错误原因:/ by zero(除以零)
- 错误位置:Test.java的第5行
2.16.5 常见错误速查表
| 错误信息 | 原因 | 解决方法 |
|---|---|---|
cannot find symbol |
变量/方法未声明或拼写错误 | 检查声明和拼写 |
';' expected |
缺少分号 | 添加分号 |
incompatible types |
类型不匹配 | 检查类型或强制转换 |
variable might not have been initialized |
变量未初始化 | 初始化变量 |
ArithmeticException: / by zero |
除数为0 | 检查除数 |
ArrayIndexOutOfBoundsException |
数组越界 | 检查数组索引 |
NullPointerException |
空指针 | 检查null |
NumberFormatException |
字符串转数字格式错误 | 验证字符串格式 |
本章小结
核心知识点
1. 注释
- 单行注释:
// - 多行注释:
/* */ - 文档注释:
/** */
2. 标识符
- 命名规则:字母、数字、下划线、$组成,不能以数字开头,不能是关键字
- 命名规范:类名大驼峰,方法和变量小驼峰,常量全大写
3. 数据类型
- 8种基本数据类型:byte、short、int、long、float、double、char、boolean
- 整数默认int,小数默认double
- long后加L,float后加f
4. 变量
- 先声明后使用,先初始化后使用
- 有作用域,同一作用域不能重名
5. 运算符
- 算术运算符:+、-、*、/、%、++、–
- 赋值运算符:=、+=、-=、*=、/=、%=
- 比较运算符:==、!=、>、<、>=、<=
- 逻辑运算符:&、|、^、!、&&、||
- 三元运算符:? :
6. 类型转换
- 自动转换:小 → 大
- 强制转换:大 → 小,可能丢失精度
7. Scanner
- nextInt()、nextDouble()、next()、nextLine()
实践练习
练习1:个人信息输入输出
编写程序,使用Scanner接收用户输入的姓名、年龄、身高、体重,并计算BMI值。
BMI = 体重(kg) / 身高²(m)
练习2:温度转换
编写程序,实现摄氏度和华氏度的相互转换。
华氏度 = 摄氏度 × 1.8 + 32
摄氏度 = (华氏度 - 32) / 1.8
练习3:简单计算器
编写程序,接收两个数和一个运算符(+、-、*、/),输出运算结果。
练习4:判断闰年
编写程序,输入年份,判断是否为闰年。
闰年条件:
1. 能被4整除但不能被100整除
2. 或者能被400整除
练习5:成绩等级判断
编写程序,输入成绩,输出等级:
- 90-100:优秀
- 80-89:良好
- 70-79:中等
- 60-69:及格
- 0-59:不及格
延伸阅读
推荐阅读:
- 《Java编程思想》第2章:一切都是对象
- 《Effective Java》第9章:通用程序设计
- Oracle Java官方教程:Language Basics
在线练习:
- LeetCode基础题
- 牛客网Java基础练习
- 洛谷入门题
思维导图
Java基础语法
├── 注释
│ ├── 单行注释 //
│ ├── 多行注释 /* */
│ └── 文档注释 /** */
│
├── 标识符
│ ├── 命名规则(硬性)
│ └── 命名规范(软性)
│
├── 数据类型
│ ├── 基本类型(8种)
│ │ ├── 整数:byte short int long
│ │ ├── 浮点:float double
│ │ ├── 字符:char
│ │ └── 布尔:boolean
│ └── 引用类型
│
├── 变量与常量
│ ├── 变量声明与初始化
│ └── final常量
│
├── 类型转换
│ ├── 自动转换(隐式)
│ └── 强制转换(显式)
│
├── 运算符
│ ├── 算术运算符
│ ├── 赋值运算符
│ ├── 比较运算符
│ ├── 逻辑运算符
│ ├── 三元运算符
│ └── 位运算符
│
└── Scanner输入
├── nextInt()
├── nextDouble()
├── next()
└── nextLine()
参考资料
官方文档
-
Java语言规范
https://docs.oracle.com/javase/specs/
Java语言的官方规范文档,详细定义语法规则 -
Java基本数据类型文档
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
官方关于数据类型的教程 -
Java运算符文档
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html
官方运算符使用教程
推荐书籍
-
《Java核心技术 卷I:基础知识》(第2-3章)
作者:Cay S. Horstmann
详细讲解Java基础语法和数据类型 -
《Head First Java》(第2-4章)
作者:Kathy Sierra, Bert Bates
以图文并茂的方式讲解变量和基本类型 -
《Java编程思想》(第2章)
作者:Bruce Eckel
深入剖析Java语法的设计思想
在线教程
-
菜鸟教程 - Java基础语法
https://www.runoob.com/java/java-basic-syntax.html
简明易懂的基础语法教程 -
廖雪峰 - Java快速入门
https://www.liaoxuefeng.com/wiki/1252599548343744/1255883772263712
系统的Java语法入门教程 -
W3Cschool - Java教程
https://www.w3cschool.cn/java/
在线学习和实践平台
视频教程
-
尚硅谷 - Java基础语法
B站搜索"尚硅谷Java基础语法"
详细讲解数据类型、运算符等知识点 -
黑马程序员 - Java基础day02-day03
B站搜索"黑马程序员Java基础"
通俗易懂的视频讲解
练习平台
-
LeetCode - 简单题库
https://leetcode.cn/problemset/all/?difficulty=EASY
通过算法题巩固基础语法 -
牛客网 - Java语法练习
https://www.nowcoder.com/exam/oj
专项练习题库 -
PTA程序设计类实验辅助平台
https://pintia.cn/
适合初学者的编程练习平台
补充资源
-
Java关键字完整列表
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html
官方关键字和保留字列表 -
Java命名规范(阿里巴巴)
https://github.com/alibaba/p3c
阿里巴巴Java开发手册,包含命名规范 -
正则表达式在线测试
https://regex101.com/
学习和测试正则表达式(高级话题)
常见问题
-
Stack Overflow - Java语法问题
https://stackoverflow.com/questions/tagged/java-syntax
查找和解决语法相关问题 -
Java基础面试题汇总
搜索"Java基础语法面试题"
巩固知识点,准备技术面试
更多推荐



所有评论(0)