「Java基本语法」运算符与表达式

6 阅读10分钟

知识点详细解析

1.Java中的运算符

运算符是Java语言中用于执行特定操作的符号,用于操作变量和值。Java提供了丰富的运算符集,可以执行各种数学、逻辑和位运算操作。运算符分为:

  1. 算术运算符:对数值进行数学运算。
  • 包括:+(加)、-(减)、*(乘)、/(除)、%(取模,求余数)、++(自增)、--(自减)
  • /对整数除法会截断小数部分,对浮点数保留小数。
  • %取余结果符号与被除数一致,例如,-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
  1. 赋值运算符:为变量赋值或执行复合赋值操作。
  • 包括:=(简单赋值)、+=(加后赋值)、-=(减后赋值)、*=(乘后赋值)、/=(除后赋值)、%=(取模后赋值)、&=(位与后赋值)、|=(位或后赋值)、^=(位异或后赋值)、<<=(左移后赋值)、>>=(右移后赋值)、>>>=(无符号右移后赋值)
  • 复合赋值运算符(如+=)会隐式进行类型转换(如byte += int自动转换为byte)。
int n = 10;
n += 5;  // 等同于 n = n + 5
System.out.println(n);  // 15
  1. 比较运算符:比较两个值,返回布尔结果(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
  1. 逻辑运算符:组合布尔表达式,控制条件逻辑。
  • 包括:&&(逻辑与)、||(逻辑或)、!(逻辑非)。
  • &&和||具有短路特性(若左侧表达式已决定结果,右侧不执行)。
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程序中最基本的计算单元,它由变量、运算符、方法调用等组成,计算后能产生一个确定的值。

表达式的基本特征

  1. 由操作数和运算符组成,例如,a + b中,a和b是操作数,+是运算符。
  2. 有确定的类型,表达式计算后会产生一个特定类型的值。
  3. 可以嵌套,表达式可以包含其他的表达式。
  4. 可以赋值,表达式的结果可以赋给变量。

相关案例与解析

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

代码解析

  1. Java源文件保存为“CircleArea.java”。
  2. *用于乘法运算,radius * radius计算半径的平方。
  3. 使用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

代码解析

  1. Java源文件保存为“DivisionDemo.java”。
  2. 整数除法直接丢弃小数部分,浮点数除法保留小数。

**案例: **取余运算的符号规则

public class ModulusDemo {
    public static void main(String[] args) {
        System.out.println("5 % 2 = " + (5 % 2)); // 输出:1
        System.out.println("-5 % 2 = " + (-5 % 2)); // 输出:-1(与被除数符号一致)
        System.out.println("5 % -2 = " + (5 % -2)); // 输出:1(与被除数符号一致)
    }
}

运行结果

5 % 2 = 1
-5 % 2 = -1
5 % -2 = 1

代码解析

  1. Java源文件保存为“ModulusDemo.java”。
  2. 取余结果的符号由被除数决定。

案例: 自增与自减

public class IncrementDemo {
    public static void main(String[] args) {
        int count = 3;
        System.out.println("初始值: " + count); // 输出:3
        System.out.println("后置自增: " + count++); // 输出:3(先使用后自增)
        System.out.println("当前值: " + count); // 输出:4
        System.out.println("前置自减: " + --count); // 输出:3(先自减后使用)
    }
}

运行结果

初始值: 3
后置自增: 3
当前值: 4
前置自减: 3

代码解析

  1. Java源文件保存为“IncrementDemo.java”。
  2. count++是后置自增,--count是前置自减。
  3. 自增/自减运算符常用于循环和计数。

2 赋值运算符

案例: 复合赋值运算符

public class AssignmentDemo {
    public static void main(String[] args) {
        int score = 80;
        score += 10; // 等价于 score = score + 10
        System.out.println("加分后: " + score); // 输出:90

        score -= 5; // 等价于 score = score - 5
        System.out.println("扣分后: " + score); // 输出:85
    }
}

运行结果

加分后: 90
扣分后: 85

代码解析

  1. Java源文件保存为“AssignmentDemo.java”。
  2. 复合赋值运算符,例如+=、-=可以简化代码,运行时可能会进行隐式进行类型转换。

案例: 复合赋值运算符的类型转换

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

代码解析

  1. Java源文件保存为“CompoundAssignment.java”。
  2. 复合赋值运算符(如+=)会自动处理类型转换,但直接使用=赋值时需显式转换。

3 比较运算符

案例: 判断年龄范围

public class AgeCheck {
    public static void main(String[] args) {
        int age = 18;
        boolean isAdult = age >= 18; // 使用 >= 运算符
        System.out.println("是否成年: " + isAdult); // 输出:true
    }
}

运行结果

是否成年: true

代码解析

  1. Java源文件保存为“AgeCheck.java”。
  2. 比较运算符返回布尔值,常用于条件判断。

案例: 字符串比较的陷阱

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

代码解析

  1. Java源文件保存为“StringComparison.java”。
  2. ==比较引用地址,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

代码解析

  1. Java源文件保存为“PermissionCheck.java”。
  2. ||表示“或”逻辑,只要有一个条件为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); // 输出:false
        System.out.println("num = " + num); // 输出:5(num++ 未执行)
    }
}

运行结果

result = false
num = 5

代码解析

  1. Java源文件保存为“ShortCircuitDemo.java”。
  2. &&左侧为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); // 输出:11

        int result2 = (a + b) * c; // 等价于 (a + b) * c
        System.out.println("(a + b) * c = " + result2); // 输出:16
    }
}

运行结果

a + b * c = 11
(a + b) * c = 16

代码解析

  1. Java源文件保存为“PrecedenceDemo.java”。
  2. 使用括号()明确优先级,避免歧义。

常见错误及解决方法

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;(结果不确定)。

解决方法: 避免在同一表达式中多次修改同一变量。

知识总结

  1. 算术运算符:支持基本数学运算,注意整数除法和取余。
  2. 赋值运算符:简化赋值操作,复合运算符支持隐式类型转换。
  3. 比较运算符:返回布尔值,字符串比较用equals()。
  4. 逻辑运算符:&&和||具有短路特性。
  5. 运算符优先级:使用括号()明确优先级,避免歧义。

理论练习

选择题:以下代码的输出是什么?

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”。