「Java基本语法」运算符与表达式
知识点详细解析
1.Java中的运算符
运算符是Java语言中用于执行特定操作的符号,用于操作变量和值。Java提供了丰富的运算符集,可以执行各种数学、逻辑和位运算操作。运算符分为:
- 算术运算符:对数值进行数学运算。
- 包括:+(加)、-(减)、*(乘)、/(除)、%(取模,求余数)、++(自增)、--(自减)
- /对整数除法会截断小数部分,对浮点数保留小数。
- %取余结果符号与被除数一致,例如,-5 % 2 = -1。
int a = 10, b = 3;
System.out.println(a + b); // 13
System.out.println(a - b); // 7
System.out.println(a * b); // 30
System.out.println(a / b); // 3 (整数除法)
System.out.println(a % b); // 1
- 赋值运算符:为变量赋值或执行复合赋值操作。
- 包括:=(简单赋值)、+=(加后赋值)、-=(减后赋值)、*=(乘后赋值)、/=(除后赋值)、%=(取模后赋值)、&=(位与后赋值)、|=(位或后赋值)、^=(位异或后赋值)、<<=(左移后赋值)、>>=(右移后赋值)、>>>=(无符号右移后赋值)
- 复合赋值运算符(如+=)会隐式进行类型转换(如byte += int自动转换为byte)。
int n = 10;
n += 5; // 等同于 n = n + 5
System.out.println(n); // 15
- 比较运算符:比较两个值,返回布尔结果(true/false)。
- 包括:==(等于)、!=(不等于)、>(大于)、<(小于)、>=(大于等于)、<=(小于等于)
- ==和!=可用于基本类型和引用类型(但引用类型比较的是地址)。
int x = 5, y = 10;
System.out.println(x == y); // false
System.out.println(x != y); // true
System.out.println(x > y); // false
- 逻辑运算符:组合布尔表达式,控制条件逻辑。
- 包括:&&(逻辑与)、||(逻辑或)、!(逻辑非)。
- &&和||具有短路特性(若左侧表达式已决定结果,右侧不执行)。
boolean t = true, f = false;
System.out.println(t && f); // false
System.out.println(t || f); // true
System.out.println(!t); // false
2.运算符优先级
运算符的优先级决定表达式中运算符的执行顺序。
运算符优先级(优先级从高到低):() → ! → * / % → + - → > < >= <= → == != → && → || → =。括号()最高,!、*、/、%次之,+、-随后,比较运算符再后,&&和||最后。
3.表达式
表达式是Java程序中最基本的计算单元,它由变量、运算符、方法调用等组成,计算后能产生一个确定的值。
表达式的基本特征
- 由操作数和运算符组成,例如,a + b中,a和b是操作数,+是运算符。
- 有确定的类型,表达式计算后会产生一个特定类型的值。
- 可以嵌套,表达式可以包含其他的表达式。
- 可以赋值,表达式的结果可以赋给变量。
相关案例与解析
1.算术运算符
案例:计算圆的面积
public class CircleArea {public static void main(String[] args) {double radius = 5.0;double area = 3.14159 * radius * radius; // 使用 * 运算符System.out.println("圆的面积: " + area); // 输出:78.53975}
}
运行结果
圆的面积: 78.53975
代码解析
- Java源文件保存为“CircleArea.java”。
- *用于乘法运算,radius * radius计算半径的平方。
- 使用double类型避免整数除法丢失精度。
案例:整数与浮点数除法对比
public class DivisionDemo {public static void main(String[] args) {int a = 5, b = 2;double c = 5.0, d = 2.0;System.out.println("整数除法: " + (a / b)); // 输出:2(截断小数)System.out.println("浮点数除法: " + (c / d)); // 输出:2.5}
}
运行结果
整数除法: 2
浮点数除法: 2.5
代码解析
- Java源文件保存为“DivisionDemo.java”。
- 整数除法直接丢弃小数部分,浮点数除法保留小数。
案例:取余运算的符号规则
public class ModulusDemo {public static void main(String[] args) {System.out.println("5 % 2 = " + (5 % 2)); // 输出:1System.out.println("-5 % 2 = " + (-5 % 2)); // 输出:-1(与被除数符号一致)System.out.println("5 % -2 = " + (5 % -2)); // 输出:1(与被除数符号一致)}
}
运行结果
5 % 2 = 1
-5 % 2 = -1
5 % -2 = 1
代码解析
- Java源文件保存为“ModulusDemo.java”。
- 取余结果的符号由被除数决定。
案例:自增与自减
public class IncrementDemo {public static void main(String[] args) {int count = 3;System.out.println("初始值: " + count); // 输出:3System.out.println("后置自增: " + count++); // 输出:3(先使用后自增)System.out.println("当前值: " + count); // 输出:4System.out.println("前置自减: " + --count); // 输出:3(先自减后使用)}
}
运行结果
初始值: 3
后置自增: 3
当前值: 4
前置自减: 3
代码解析
- Java源文件保存为“IncrementDemo.java”。
- count++是后置自增,--count是前置自减。
- 自增/自减运算符常用于循环和计数。
2.赋值运算符
案例:复合赋值运算符
public class AssignmentDemo {public static void main(String[] args) {int score = 80;score += 10; // 等价于 score = score + 10System.out.println("加分后: " + score); // 输出:90score -= 5; // 等价于 score = score - 5System.out.println("扣分后: " + score); // 输出:85}
}
运行结果
加分后: 90
扣分后: 85
代码解析
- Java源文件保存为“AssignmentDemo.java”。
- 复合赋值运算符,例如+=、-=可以简化代码,运行时可能会进行隐式进行类型转换。
案例:复合赋值运算符的类型转换
public class CompoundAssignment {public static void main(String[] args) {byte x = 10;x += 5; // 等价于 x = (byte)(x + 5),隐式类型转换System.out.println("x = " + x); // 输出:15// x = x + 5; // 编译错误:需要显式类型转换}
}
运行结果
x = 15
代码解析
- Java源文件保存为“CompoundAssignment.java”。
- 复合赋值运算符(如+=)会自动处理类型转换,但直接使用=赋值时需显式转换。
3.比较运算符
案例:判断年龄范围
public class AgeCheck {public static void main(String[] args) {int age = 18;boolean isAdult = age >= 18; // 使用 >= 运算符System.out.println("是否成年: " + isAdult); // 输出:true}
}
运行结果
是否成年: true
代码解析
- Java源文件保存为“AgeCheck.java”。
- 比较运算符返回布尔值,常用于条件判断。
案例:字符串比较的陷阱
public class StringComparison {public static void main(String[] args) {String s1 = "hello";String s2 = new String("hello");System.out.println("s1 == s2: " + (s1 == s2)); // 输出:false(比较地址)System.out.println("s1.equals(s2): " + s1.equals(s2)); // 输出:true(比较内容)}
}
运行结果
s1 == s2: false
s1.equals(s2): true
代码解析
- Java源文件保存为“StringComparison.java”。
- ==比较引用地址,equals()比较内容。
4.逻辑运算符
案例:判断用户权限
public class PermissionCheck {public static void main(String[] args) {boolean isAdmin = true;boolean hasAccess = false;boolean canAccess = isAdmin || hasAccess; // 使用 || 运算符System.out.println("是否可访问: " + canAccess); // 输出:true}
}
运行结果
是否可访问: true
代码解析
- Java源文件保存为“PermissionCheck.java”。
- ||表示“或”逻辑,只要有一个条件为true,结果即为true。
案例:短路特性验证
public class ShortCircuitDemo {public static void main(String[] args) {int num = 5;boolean result = (num > 10) && (num++ > 0); // 左侧为 false,右侧不执行System.out.println("result = " + result); // 输出:falseSystem.out.println("num = " + num); // 输出:5(num++ 未执行)}
}
运行结果
result = false
num = 5
代码解析
- Java源文件保存为“ShortCircuitDemo.java”。
- &&左侧为false时,右侧表达式不执行(短路)。
5.运算符优先级
案例:优先级规则
public class PrecedenceDemo {public static void main(String[] args) {int a = 5, b = 3, c = 2;int result1 = a + b * c; // 等价于 a + (b * c)System.out.println("a + b * c = " + result1); // 输出:11int result2 = (a + b) * c; // 等价于 (a + b) * cSystem.out.println("(a + b) * c = " + result2); // 输出:16}
}
运行结果
a + b * c = 11
(a + b) * c = 16
代码解析
- Java源文件保存为“PrecedenceDemo.java”。
- 使用括号()明确优先级,避免歧义。
常见错误及解决方法
1.整数除法丢失精度
错误:int x = 5 / 2;(结果为2)。
解决方法:使用浮点数,例如,double x = 5.0 / 2;。
2.字符串比较错误
错误:if ("a" == "b")(比较引用而非内容)。
解决方法:使用equals()方法,例如,"a".equals("b")。
3.运算符优先级错误
错误:if (a > b && b < c || c == 2)(逻辑不明确)。
解决方法:使用括号明确优先级。
4.自增/自减混淆
错误:int x = 5; int y = x++ + ++x;(结果不确定)。
解决方法:避免在同一表达式中多次修改同一变量。
知识总结
- 算术运算符:支持基本数学运算,注意整数除法和取余。
- 赋值运算符:简化赋值操作,复合运算符支持隐式类型转换。
- 比较运算符:返回布尔值,字符串比较用equals()。
- 逻辑运算符:&&和||具有短路特性。
- 运算符优先级:使用括号()明确优先级,避免歧义。
理论练习
选择题:以下代码的输出是什么?
int x = 10;
System.out.println(x++ + ++x);
A.0 B.21 C.22 D.23
答案:D
解析:x++先返回10后自增为11,++x先自增为12后返回12,结果为10 + 12 = 22。
选择题:以下代码的输出是什么?
int x = 10;
System.out.println(x++ + --x + x);
A.29 B.30 C.31 D.32
答案:B
解析:x++先返回10后自增为11,--x先自减为10后返回10,x当前为10,结果为10 + 10 + 10 = 30。
选择题:以下运算符优先级最高的是?
A.&& B.+ C.* D.||
答案:C
解析:*优先级高于+,+优先级高于&&和||。
选择题:以下运算符优先级最低的是?
A.= B.&& C.+ D.%
答案:A
解析:赋值运算符=优先级最低。
填空题:字符串比较需用________方法。
答案:equals
填空题:&&和||具有________特性。
答案:短路
填空题:5 % -2的结果是________。
答案:1
判断题:5 / 2的结果是2.5。
答案:×,应为2
判断题:"a" == "a"返回true。
答案:√。
判断题:"a".equals(new String("a"))返回true。(√)
答案:√。
判断题:int x = 5; x += 2.5;会编译错误。
答案:×。隐式转换为int,结果为7。
实操练习
练习:编写程序,计算长方形的周长(周长 = 2 * (长 + 宽))。
参考答案
public class RectanglePerimeter {public static void main(String[] args) {double length = 5.0, width = 3.0;double perimeter = 2 * (length + width);System.out.println("长方形的周长: " + perimeter); // 输出:16.0}
}
运行结果
长方形的周长: 16.0
说明:Java源文件保存为“RectanglePerimeter.java”。
练习:编写程序,计算三角形的面积(面积 = 底 * 高 / 2)。
参考答案
public class TriangleArea {public static void main(String[] args) {double base = 10.0, height = 5.0;double area = base * height / 2;System.out.println("三角形的面积: " + area); // 输出:25.0}
}
运行结果
三角形的面积: 25.0
说明:Java源文件保存为“TriangleArea.java”。
练习:编写程序,判断一个数是否为奇数(使用%运算符)。
参考答案
public class OddNumber {public static void main(String[] args) {int num = 7;boolean isOdd = num % 2 != 0;System.out.println("是否为奇数: " + isOdd); // 输出:true}
}
运行结果
是否为奇数: true
说明:Java源文件保存为“OddNumber.java”。
练习:编写程序,判断一个数是否为偶数(使用%运算符)。
参考答案
public class EvenNumber {public static void main(String[] args) {int num = 8;boolean isEven = num % 2 == 0;System.out.println("是否为偶数: " + isEven); // 输出:true}
}
运行结果
是否为偶数: true
说明:Java源文件保存为“EvenNumber.java”。
练习:编写程序,使用逻辑运算符判断一个数是否在[5, 15]范围内。
参考答案
public class RangeCheck {public static void main(String[] args) {int num = 10;boolean inRange = num >= 5 && num <= 15;System.out.println("是否在范围内: " + inRange); // 输出:true}
}
运行结果
是否在范围内: true
说明:Java源文件保存为“RangeCheck.java”。
练习:编写程序,使用逻辑运算符判断一个数是否在[10, 20]或[30, 40]范围内。
参考答案
public class RangeCheck {public static void main(String[] args) {int num = 15;boolean inRange = (num >= 10 && num <= 20) || (num >= 30 && num <= 40);System.out.println("是否在范围内: " + inRange); // 输出:true}
}
运行结果
是否在范围内: true
说明:Java源文件保存为“RangeCheck.java”。
练习:编写程序,判断用户输入的年份是否为闰年(能被4整除但不能被100整除,或能被400整除)。
参考答案
import java.util.Scanner;public class LeapYearCheck {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);System.out.print("输入年份: ");int year = scanner.nextInt();boolean isLeap = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);System.out.println("是否为闰年: " + isLeap);}
}
运行结果
输入年份: 2025
是否为闰年: false
说明:Java源文件保存为“LeapYearCheck.java”。
练习:编写程序,计算用户输入的两个整数的和、差、积、商和余数。
参考答案
import java.util.Scanner;public class Calculator {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);System.out.print("输入第一个整数: ");int a = scanner.nextInt();System.out.print("输入第二个整数: ");int b = scanner.nextInt();System.out.println("和: " + (a + b));System.out.println("差: " + (a - b));System.out.println("积: " + (a * b));System.out.println("商: " + (a / b)); // 注意整数除法System.out.println("余数: " + (a % b));}
}
运行结果
输入第一个整数: 15
输入第二个整数: 7
和: 22
差: 8
积: 105
商: 2
余数: 1
说明:Java源文件保存为“Calculator.java”。
练习:编写程序,计算用户输入的两个浮点数的和、差、积、商和余数(商保留两位小数)。
参考答案
import java.util.Scanner;public class FloatCalculator {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);System.out.print("输入第一个浮点数: ");double a = scanner.nextDouble();System.out.print("输入第二个浮点数: ");double b = scanner.nextDouble();System.out.println("和: " + (a + b));System.out.println("差: " + (a - b));System.out.println("积: " + (a * b));System.out.printf("商: %.2f\n", a / b); // 保留两位小数System.out.println("余数: " + (a % b));}
}
运行结果
输入第一个浮点数: 25.8
输入第二个浮点数: 11.6
和: 37.4
差: 14.200000000000001
积: 299.28
商: 2.22余数: 2.6000000000000014
说明:Java源文件保存为“FloatCalculator.java”。