第四章 类与对象——面向对象编程入门

一、本章知识回顾

面向对象基础概念表格
知识点 说明
类 对象的模板,描述一类事物的共同特征
对象 类的具体实例
成员变量 对象的属性(状态)
成员方法 对象的行为(功能)
构造方法 创建对象时初始化成员变量
this关键字 指向当前对象的引用
对象的组合 一个类把其他类的对象作为成员

二、为什么需要类与对象?

2.1 问题引入

假设要处理小明养的两只狗的信息:

狗名 年龄 颜色
小白 3岁 白色
小花 10岁 花色

表格转换结果
狗名 年龄 颜色
小白 3岁 白色
小花 10岁 花色
如果用之前学过的数组来处理:

String[] dog1 = {“小白”, “3”, “白色”};
String[] dog2 = {“小花”, “10”, “花色”};

AI写代码
java
运行
数组方式的问题:

数据类型不明确(年龄”3”是字符串,不方便计算)

通过下标获取信息(dog1[0]是名字,dog1[1]是年龄,容易混淆)

不能体现狗的行为(如”叫”、”跑”等)

解决方式:用类来定义狗的特征和行为,用对象来表示具体的某只狗。

三、类的定义
3.1 类的基本结构
类是Java中最基本的”模板”,用来描述一类事物的属性(成员变量)和行为(成员方法)。

java

class Dog {
// 1. 成员变量(属性)
String name; // 名字
int age; // 年龄
String color; // 颜色

// 2. 成员方法(行为)
void bark() {
    System.out.println(name + ":汪汪汪!");
}

void run() {
    System.out.println(name + "正在奔跑");
}

void showInfo() {
    System.out.println("名字:" + name + ",年龄:" + age + "岁,颜色:" + color);
}

}
3.2 成员变量
位置:在类中、方法外部定义

作用:描述对象的属性(状态)

默认值:即使不赋值,也有默认初始值

类型 默认值
int 0
double 0.0
boolean false
char ‘\u0000’
引用类型(String等) null
3.3 成员方法
位置:在类中定义

作用:描述对象的行为(功能)

结构:修饰符 + 返回值类型 + 方法名 + 参数列表 + 方法体

java

// 方法结构示例
public void bark() { // 无返回值,无参数
System.out.println(“叫”);
}

public int add(int a, int b) { // 有返回值,有参数
return a + b;
}
四、对象的创建与使用
4.1 创建对象(实例化)
使用 new 关键字 + 构造方法创建对象:

java

public class DogTest {
public static void main(String[] args) {
// 创建Dog类的对象
Dog dog1 = new Dog(); // 声明 + 创建 + 赋值

    // 或者分两步写
    Dog dog2;              // 1.声明对象变量
    dog2 = new Dog();      // 2.创建对象(分配内存)
}

}
4.2 使用对象
通过 对象名.成员变量 和 对象名.成员方法() 来访问:

java

public class DogTest {
public static void main(String[] args) {
// 创建对象
Dog dog1 = new Dog();
Dog dog2 = new Dog();

    // 给成员变量赋值
    dog1.name = "小白";
    dog1.age = 3;
    dog1.color = "白色";
    
    dog2.name = "小花";
    dog2.age = 10;
    dog2.color = "花色";
    
    // 调用成员方法
    dog1.showInfo();   // 输出:名字:小白,年龄:3岁,颜色:白色
    dog1.bark();       // 输出:小白:汪汪汪!
    
    dog2.showInfo();   // 输出:名字:小花,年龄:10岁,颜色:花色
    dog2.run();        // 输出:小花正在奔跑
}

}
运行结果:

text

名字:小白,年龄:3岁,颜色:白色
小白:汪汪汪!
名字:小花,年龄:10岁,颜色:花色
小花正在奔跑
4.3 类与对象的关系图
text

┌─────────────────────────────────────┐
│ 类(模板) │
│ ┌─────────────────────────────────┐ │
│ │ class Dog { │ │
│ │ String name; // 成员变量 │ │
│ │ int age; │ │
│ │ void bark() {…} // 方法 │ │
│ │ } │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────┘
│
│ 实例化(new)
↓
┌───────────────────────┐ ┌───────────────────────┐
│ 对象1(实例1) │ │ 对象2(实例2) │
│ ┌─────────────────┐ │ │ ┌─────────────────┐ │
│ │ name = “小白” │ │ │ │ name = “小花” │ │
│ │ age = 3 │ │ │ │ age = 10 │ │
│ │ color = “白色” │ │ │ │ color = “花色” │ │
│ └─────────────────┘ │ │ └─────────────────┘ │
└───────────────────────┘ └───────────────────────┘
核心理解:

类:图纸(抽象)

对象:根据图纸造出的房子(具体)

同一个类可以创建多个对象,每个对象有自己的属性值

五、构造方法
5.1 什么是构造方法?
构造方法是专门用来创建对象时初始化成员变量的特殊方法。

特点:

方法名与类名相同

没有返回值类型(连void都不写)

创建对象时自动调用

5.2 无参构造方法
java

class Dog {
String name;
int age;

// 无参构造方法
Dog() {
    System.out.println("一只新的狗被创建了");
}

}

public class Test {
public static void main(String[] args) {
Dog dog = new Dog(); // 自动调用构造方法,输出:一只新的狗被创建了
}
}
5.3 有参构造方法
java

class Dog {
String name;
int age;
String color;

// 有参构造方法
Dog(String n, int a, String c) {
    name = n;
    age = a;
    color = c;
    System.out.println("创建了:" + name);
}

void showInfo() {
    System.out.println("名字:" + name + ",年龄:" + age + ",颜色:" + color);
}

}

public class Test {
public static void main(String[] args) {
// 创建对象时直接传入参数
Dog dog1 = new Dog(“小白”, 3, “白色”);
Dog dog2 = new Dog(“小花”, 10, “花色”);

    dog1.showInfo();  // 名字:小白,年龄:3,颜色:白色
    dog2.showInfo();  // 名字:小花,年龄:10,颜色:花色
}

}
5.4 注意事项
情况 说明
没有定义任何构造方法 系统自动提供无参构造方法
定义了有参构造方法 系统不再提供无参构造方法
想同时使用两种 需要重载构造方法(手动写两个)
六、this关键字
6.1 解决命名冲突
当成员变量和局部变量(包括参数)同名时,this.成员变量 表示成员变量。

java

class Dog {
String name;
int age;

// 参数名和成员变量名相同
Dog(String name, int age) {
    this.name = name;  // this.name 是成员变量,name 是参数
    this.age = age;
}

void showInfo() {
    System.out.println("名字:" + name + ",年龄:" + age);
}

}
为什么需要this?

如果不写this,会发生”局部变量覆盖成员变量”:

java

// 错误写法
Dog(String name, int age) {
name = name; // 左边和右边都是参数name,成员变量name没有被赋值
age = age; // 同样的问题
}
6.2 this的其他用法
java

class Dog {
String name;

Dog() {
    this("无名");  // 调用本类的有参构造方法
}

Dog(String name) {
    this.name = name;
}

}
七、对象的组合
一个类可以把其他类的对象作为自己的成员变量,这叫对象的组合。

示例:人养狗
java

// 狗类
class Dog {
String name;
int age;

Dog(String name, int age) {
    this.name = name;
    this.age = age;
}

void bark() {
    System.out.println(name + ":汪汪!");
}

}

// 人类(组合了Dog类)
class Person {
String name;
Dog pet; // 把Dog对象作为成员变量

Person(String name, Dog pet) {
    this.name = name;
    this.pet = pet;
}

void walkPet() {
    System.out.println(name + "正在遛 " + pet.name);
    pet.bark();
}

void showInfo() {
    System.out.print(name + "的宠物:");
    System.out.println("名字:" + pet.name + ",年龄:" + pet.age + "岁");
}

}

public class Test {
public static void main(String[] args) {
// 先创建狗
Dog dog = new Dog(“小白”, 3);

    // 再创建人(把狗作为参数传入)
    Person person = new Person("小明", dog);
    
    person.showInfo();   // 小明的宠物:名字:小白,年龄:3岁
    person.walkPet();    // 小明正在遛小白 \n 小白:汪汪!
}

}
运行结果:

text

小明的宠物:名字:小白,年龄:3岁
小明正在遛小白
小白:汪汪!
八、完整示例:有理数类(教材例题)
根据教材第4章的有理数类例题,以下是一个完整的封装示例:

java

/**

  • 有理数类(封装分数)

  • 成员变量:分子、分母

  • 成员方法:加法、减法、乘法、除法、化简
    */
    class Rational {
    int numerator; // 分子
    int denominator; // 分母

    // 构造方法
    Rational(int numerator, int denominator) {
    this.numerator = numerator;
    this.denominator = denominator;
    reduce(); // 创建时自动化简
    }

    // 求最大公约数(用于化简)
    int gcd(int a, int b) {
    return b == 0 ? a : gcd(b, a % b);
    }

    // 化简分数
    void reduce() {
    int g = gcd(numerator, denominator);
    numerator /= g;
    denominator /= g;
    }

    // 加法
    Rational add(Rational r) {
    int newNum = this.numerator * r.denominator + r.numerator * this.denominator;
    int newDen = this.denominator * r.denominator;
    return new Rational(newNum, newDen);
    }

    // 减法
    Rational subtract(Rational r) {
    int newNum = this.numerator * r.denominator - r.numerator * this.denominator;
    int newDen = this.denominator * r.denominator;
    return new Rational(newNum, newDen);
    }

    // 输出分数
    void display() {
    if (denominator == 1) {
    System.out.println(numerator);
    } else {
    System.out.println(numerator + “/“ + denominator);
    }
    }

}

public class RationalTest {
public static void main(String[] args) {
Rational r1 = new Rational(1, 3); // 1/3
Rational r2 = new Rational(2, 5); // 2/5

    System.out.print("1/3 + 2/5 = ");
    r1.add(r2).display();                // 11/15
    
    System.out.print("1/3 - 2/5 = ");
    r1.subtract(r2).display();           // -1/15
}

}
九、常见错误与注意点
错误写法 正确写法 说明
Dog dog; dog.name = “小白”; Dog dog = new Dog(); 必须先创建对象才能使用
class dog { … } class Dog { … } 类名首字母大写(规范)
构造方法写了返回值类型 Dog() { }(无void) 构造方法不能有返回值
this 在静态方法中使用 只能在非静态方法中使用 static方法中不能用this
忘记写构造方法导致无法初始化 提供合适的构造方法 或使用setter方法赋值
十、小结
本章学习了:

类的定义:成员变量 + 成员方法

对象的创建:使用 new 关键字

构造方法:与类同名,无返回值,用于初始化

this关键字:区分成员变量和局部变量

对象的组合:一个类包含其他类的对象

核心代码模板:

java

class 类名 {
// 1. 成员变量
数据类型 变量名;

// 2. 构造方法
类名(参数列表) {
    this.成员变量 = 参数;
}

// 3. 成员方法
返回值类型 方法名(参数列表) {
    // 方法体
}

}

// 使用
类名 对象名 = new 类名(参数);
对象名.方法名();

JAVA作业:素数查找——用循环和分支解决问题

一、问题引入

什么是素数?

素数(质数):大于1的自然数,除了1和它本身以外,不能被其他自然数整除。

例如:

  • 7是素数(只能被1和7整除)
  • 8不是素数(还能被2和4整除)

二、判断一个数是否为素数

2.1 核心思路

要判断一个数num是否为素数,只需要检查:

  • 从2开始,到num-1结束
  • 用每个数去除num
  • 如果发现任何一个能整除,说明num不是素数

2.2 基础代码

public class IsPrime {
    public static void main(String[] args) {
        int num = 17;
        boolean isPrime = true;  // 先假设是素数
        
        // for循环:从2检查到num-1
        for (int i = 2; i < num; i++) {
            if (num % i == 0) {      // 如果能整除
                isPrime = false;      // 不是素数
                break;                // 提前结束循环
            }
        }
        
        if (isPrime) {
            System.out.println(num + "是素数");
        } else {
            System.out.println(num + "不是素数");
        }
    }
}
2.3 代码逐行解释
代码	知识点	说明
for (int i = 2; i < num; i++)	for循环	初始化i=2;条件i<num;每次i+1
num % i	算术运算符%	取余运算,得到num除以i的余数
num % i == 0	关系运算符==	判断余数是否等于0
if (num % i == 0)	if条件语句	条件成立时执行
isPrime = false	赋值运算符=	把false赋值给isPrime
break	跳转语句	跳出整个循环
2.4 程序流程图
text

开始
  ↓
输入num = 17
  ↓
假设isPrime = true
  ↓
i从2开始 ──────→ i=2
  ↓              ↓
i < num? ──→ 2<17? 是
  ↓              ↓
num % i == 0?  17%2==1? 否
  ↓              ↓
i++ → i=3       (继续循环)
  ↓
... 一直检查到i=16
  ↓
i=17时,17<17? 否,退出循环
  ↓
isPrime仍为true
  ↓
输出"17是素数"
  ↓
结束
三、找出某个范围内的所有素数
3.1 需求
找出101到200之间所有的素数。

3.2 思路
外层循环:遍历101到200的每个数

内层循环:判断当前数是否为素数

计数器:统计素数个数

3.3 完整代码
java

public class FindPrimes {
    public static void main(String[] args) {
        int start = 101;
        int end = 200;
        int count = 0;
        
        System.out.println(start + "到" + end + "之间的素数有:");
        
        // 外层循环:遍历每个要判断的数
        for (int num = start; num <= end; num++) {
            
            boolean isPrime = true;  // 假设当前数是素数
            
            // 内层循环:检查是否有因数
            // 只需要检查到 num-1
            for (int i = 2; i < num; i++) {
                if (num % i == 0) {
                    isPrime = false;  // 找到因数,不是素数
                    break;            // 跳出内层循环
                }
            }
            
            // 如果是素数,输出并计数
            if (isPrime) {
                System.out.print(num + " ");
                count++;
            }
        }
        
        System.out.println("\n共有 " + count + " 个素数");
    }
}
3.4 运行结果
text

101到200之间的素数有:
101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 
共有 21 个素数
四、优化:平方根优化
4.1 为什么要优化?
上面的代码中,判断一个数num,需要检查2到num-1。如果num=199,需要检查197次,效率很低。

4.2 优化原理
如果num不是素数,那么它一定可以写成:num = a × b

其中a和b中,至少有一个 ≤ √num

因此,我们只需要检查到√num就可以了。

4.3 优化后的代码
java

public class FindPrimesOptimized {
    public static void main(String[] args) {
        int start = 101;
        int end = 200;
        int count = 0;
        
        System.out.println(start + "到" + end + "之间的素数有:");
        
        for (int num = start; num <= end; num++) {
            if (isPrime(num)) {
                System.out.print(num + " ");
                count++;
            }
        }
        
        System.out.println("\n共有 " + count + " 个素数");
    }
    
    /**
     * 判断素数(平方根优化版)
     */
    public static boolean isPrime(int num) {
        // 小于2的不是素数
        if (num < 2) {
            return false;
        }
        
        // 只需要检查到平方根
        for (int i = 2; i <= Math.sqrt(num); i++) {
            if (num % i == 0) {
                return false;  // 有因数,不是素数
            }
        }
        return true;  // 没有因数,是素数
    }
}
4.4 优化效果对比
方法	判断199需要检查的次数
原始方法(检查到num-1)	197次
平方根优化(检查到√199≈14)	13次
快了约15倍!

五、常见错误提醒
错误写法	正确写法	说明
if (num % i = 0)	if (num % i == 0)	判断相等要用==,单个=是赋值
for (int i=2; i<num; i++) 不加大括号	建议加大括号 {}	循环体多条语句时需要大括号
忘记写break	找到因数后写break	不写会继续循环,浪费性能
内层循环从1开始	从2开始	任何数都能被1整除,从1开始会误判
六、小结
本章通过“查找素数”这个案例,实践了以下知识点:

for循环:遍历范围、嵌套使用

if语句:条件判断

运算符%:判断整除

关系运算符:<、≤(用<=表示)、==

break语句:提前跳出循环

平方根优化:提升算法效率

核心代码模板(记住这个就够了):

java

public static boolean isPrime(int num) {
    if (num < 2) return false;
    for (int i = 2; i <= Math.sqrt(num); i++) {
        if (num % i == 0) return false;
    }
    return true;
}

Java编程作业:枚举类型的三个经典应用场景(第三章)

一、什么是枚举

枚举(Enum)是Java中一种特殊的类,用于定义一组固定的常量。比如星期、季节、订单状态等,用枚举表示比用int或String更安全、更清晰。

基本语法:

enum Weekday {
MON, TUE, WED, THU, FRI, SAT, SUN
}
AI写代码
java
运行
枚举自带values()、ordinal()等方法,还可以添加属性和自定义方法。

二、场景1:状态/类型定义(最常用!)

用枚举表示有限个状态或类型

适用场景

  • 订单状态(待支付、已支付、已发货、已完成)
  • 用户角色(管理员、普通用户、访客)
  • 任务优先级(高、中、低)

订单状态管理代码示例
enum OrderState {
PENDING, // 待支付
PAID, // 已支付
SHIPPED, // 已发货
COMPLETED, // 已完成
CANCELLED; // 已取消

// 判断是否可以取消
public boolean isCancelable() {
return this == PENDING || this == PAID;
}
}

class Order {
private int id;
private OrderState state;

public Order(int id) {
this.id = id;
this.state = OrderState.PENDING;
}

public void pay() {
if (state == OrderState.PENDING) {
state = OrderState.PAID;
System.out.println(“订单” + id + “支付成功”);
} else {
System.out.println(“订单” + id + “状态异常,无法支付”);
}
}

public void cancel() {
if (state.isCancelable()) {
state = OrderState.CANCELLED;
System.out.println(“订单” + id + “已取消”);
} else {
System.out.println(“订单” + id + “当前状态不可取消”);
}
}

public void showState() {
System.out.println(“订单” + id + “状态:” + state);
}
}

public class Demo1_State {
public static void main(String[] args) {
Order order = new Order(1001);
order.showState(); // 待支付
order.pay(); // 支付成功
order.cancel(); // 已支付状态下可取消
order.showState(); // 已取消
}
}
AI写代码
java
运行

运行结果
订单1001状态:PENDING
订单1001支付成功
订单1001已取消
订单1001状态:CANCELLED
AI写代码
三、场景2:策略模式(替换大量 if/else)

每个枚举常量实现自己的业务逻辑,消除长长的分支判断

适用场景

  • 计算器(加、减、乘、除)
  • 折扣计算(打折、满减、赠品)
  • 排序算法 (升序、降序)

代码实现
enum Calculator {
ADD {
public double apply(double a, double b) {
return a + b;
}
},
SUB {
public double apply(double a, double b) {
return a - b;
}
},
MUL {
public double apply(double a, double b) {
return a * b;
}
},
DIV {
public double apply(double a, double b) {
if (b == 0) throw new ArithmeticException(“除数不能为0”);
return a / b;
}
};

public abstract double apply(double a, double b);
}

public class Demo2_Strategy {
public static void main(String[] args) {
double x = 10, y = 3;
System.out.println(x + “ + “ + y + “ = “ + Calculator.ADD.apply(x, y));
System.out.println(x + “ - “ + y + “ = “ + Calculator.SUB.apply(x, y));
System.out.println(x + “ * “ + y + “ = “ + Calculator.MUL.apply(x, y));
System.out.println(x + “ / “ + y + “ = “ + Calculator.DIV.apply(x, y));
}
}
AI写代码
java
运行

运行结果
10.0 + 3.0 = 13.0
10.0 - 3.0 = 7.0
10.0 * 3.0 = 30.0
10.0 / 3.0 = 3.3333333333333335
AI写代码
代码优势
传统 if-else 实现方式:

if (op.equals(“ADD”)) {
return a + b;
} else if (op.equals(“SUB”)) {
return a - b;
}
// 其他操作…
AI写代码
java
运行
枚举策略模式优势:

代码结构更清晰
扩展性更强
减少重复代码
类型安全
四、场景3:统一返回码(后端接口必备)

用枚举管理API返回的状态码 和提示信息

适用场景

  • RESTful API 响应(成功码200,错误码400/401/500等)
  • 业务错误码(用户不存在、密码错误等)

统一响应封装代码示例
enum ResultCode {
SUCCESS(200, “成功”),
BAD_REQUEST(400, “请求参数错误”),
UNAUTHORIZED(401, “未授权”),
NOT_FOUND(404, “资源不存在”),
SERVER_ERROR(500, “服务器内部错误”),
USER_NOT_EXIST(1001, “用户不存在”),
PASSWORD_WRONG(1002, “密码错误”);

private final int code;
private final String msg;

ResultCode(int code, String msg) {
    this.code = code;
    this.msg = msg;
}

public int getCode() { return code; }
public String getMsg() { return msg; }

}

class ApiResult {
private int code;
private String message;
private Object data;

private ApiResult(int code, String message, Object data) {
    this.code = code;
    this.message = message;
    this.data = data;
}

public static ApiResult success(Object data) {
    return new ApiResult(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMsg(), data);
}

public static ApiResult error(ResultCode resultCode) {
    return new ApiResult(resultCode.getCode(), resultCode.getMsg(), null);
}

@Override
public String toString() {
    return "{code:" + code + ", message:" + message + ", data:" + data + "}";
}

}

public class Demo3_ResultCode {
public static void main(String[] args) {
// 模拟登录接口返回
String username = “test”;
String password = “123”;

    if (!"admin".equals(username)) {
        System.out.println(ApiResult.error(ResultCode.USER_NOT_EXIST));
    } else if (!"123456".equals(password)) {
        System.out.println(ApiResult.error(ResultCode.PASSWORD_WRONG));
    } else {
        System.out.println(ApiResult.success("登录成功,token=xxx"));
    }

    // 打印所有返回码
    System.out.println("\n所有返回码:");
    for (ResultCode code : ResultCode.values()) {
        System.out.println(code.getCode() + " -> " + code.getMsg());
    }
}

}
AI写代码
java
运行

运行结果示例
{code:1001, message:用户不存在, data:null}

所有返回码:
200 -> 成功
400 -> 请求参数错误
401 -> 未授权
404 -> 资源不存在
500 -> 服务器内部错误
1001 -> 用户不存在
1002 -> 密码错误
AI写代码

五、总结

枚举的高级应用场景
场景 解决的问题 技术要点
状态/类型定义 避免魔法数字/字符串 枚举常量 + 属性 + 方法
策略模式 消除大量 if-else 抽象方法 + 常量各自实现
统一返回码 集中管理错误码 枚举 + 自定义构造器
枚举不仅仅是“常量列表”,更是一种强大的面向对象 工具。掌握这三种用法可以让代码更优雅、更安全。

六、作业心得

本次作业让我深刻理解了枚举在实际开发中的价值,尤其是策略模式替换if-else的思路,非常实用。

Java学习笔记(三):运算符、表达式与控制语句

一、学习内容

学习了《Java面向对象程序设计(第4版)》第三章,主要内容包括:

  1. 算术运算符与算术表达式
  2. 关系运算符与关系表达式
  3. 逻辑运算符与逻辑表达式
  4. 赋值运算符与赋值表达式
  5. 位运算符
  6. instanceof 运算符
  7. 一般表达式
  8. 语句概述
  9. 控制语句(if、switch、循环)

二、重点知识整理

2.1 算术运算符

运算符表格
运算符 含义 示例 结果(示例)
+ 加 5 + 3 8
- 减 5 - 3 2
* 乘 5 * 3 15
/ 除 5 / 2 2(整数除法)
% 取余 5 % 2 1
++ 自增 i++ 或 ++i 变量加1
– 自减 i– 或 –i 变量减1

注意:整数除法会舍弃小数部分,想要保留小数需要用浮点数。

自增运算符的细节(重要!):

int a = 5;
int b = a++; // 先赋值(b=5),后自增(a=6)
int c = ++a; // 先自增(a=7),后赋值(c=7)
System.out.println(“a=” + a); // 7
System.out.println(“b=” + b); // 5
System.out.println(“c=” + c); // 7
AI写代码
java
运行
这个代码块展示了Java中的自增操作符(++)的两种用法:后缀(a++)和前缀(++a),以及它们的执行顺序对变量值的影响。注释部分解释了关键步骤的行为。

2.2 关系运算符

运算符与含义对照表
运算符 含义 示例

大于 a > b
< 小于 a < b
= 大于等于 a >= b
<= 小于等于 a <= b
== 等于 a == b
!= 不等于 a != b
关系表达式的结果是布尔值:true 或 false

2.3 逻辑运算符

运算符 含义 规则
&& 逻辑与 两边操作数都为 true 时,结果才为 true
|| 逻辑或 当至少一边为真时结果为真
! 逻辑非 取反操作,true 变 false,false 变 true
短路特性(重要!):

// 示例1: && 运算符的短路行为(左侧为false时,右侧不执行)
int a = 10;
if (a > 100 && ++a > 0) { // a > 100 是false,因此++a不会执行
// 这个代码块不会执行
}
System.out.println(a); // 输出: 10,因为++a未执行

// 示例2: || 运算符的短路行为(左侧为true时,右侧不执行)
int b = 10;
if (b > 5 || ++b > 0) { // b > 5 是true,因此++b不会执行
// 这个代码块会执行
}
System.out.println(b); // 输出: 10,因为++b未执行

AI写代码
java
运行

2.4 赋值运算符

以下是常见赋值运算符的表格,列出了它们的含义、使用示例以及等价形式。这些运算符在编程中常用于简化赋值操作,提高代码可读性。表格基于您提供的内容整理,并确保所有数学表达式使用…
.
.
.
…格式进行呈现。

运算符 含义 示例 等价于
= 赋值 a = 10 -
+= 加后赋值 a += 5 a = a + 5
-= 减后赋值 a -= 5 a = a - 5
*= 乘后赋值 a *= 5 a = a *5
/= 除后赋值 a /= 5 a = a / 5
%= 取余后赋值 a %= 5
a = a % 5

2.5 运算符优先级(从高到低)

以下是您提供的运算符优先级列表格式化为规范的表格:

优先级 运算符
1(最高) (); []; .
2 ++ ;– ;!(单目运算符)
3 *; / ;%
4 +; -
5 < > ;<= ;>=
6 == ;!=
7 &&
8 ||
9(最低) = ;+= ;-= (等赋值运算符)

建议:记不清优先级时,用 () 括号明确顺序,代码也更易读。

2.6 instanceof 运算符

判断一个对象是否属于某个类(第4章会详细讲,这里先了解)

String name = “张三”;
boolean result = name instanceof String; // true
int[] arr = new int[5];
boolean result2 = arr instanceof int[]; // true

AI写代码
java
运行
2.7 语句分类

类型 说明 示例
方法调用语句 调用方法 System.out.println(“hello”);
表达式语句 以分号结尾的表达式 a = 10; i++;
复合语句 用{}括起来的多条语句 { int x=1; x++; }
空语句 只有一个分号 ;
控制语句 分支、循环等 if() for() while()
三、控制语句详解

3.1 条件分支语句

  1. if语句
    if语句用于基于布尔条件进行分支判断。它有多种形式,从简单到复杂。

单分支if
当条件为true时执行代码块。

if (条件) {
// 条件为true时执行
}
AI写代码
java
运行
示例:检查数字是否为正数。
int num = 5;
if (num > 0) {
System.out.println(“数字是正数”);
}
AI写代码
java
运行
双分支if-else
当条件为true时执行一个分支,否则执行另一个分支。

if (条件) {
// 条件为true时执行
} else {
// 条件为false时执行
}
AI写代码
java
运行
示例:判断数字是否偶数。
int num = 4;
if (num % 2 == 0) {
System.out.println(“数字是偶数”);
} else {
System.out.println(“数字是奇数”);
}
AI写代码
java
运行
多分支if-else if-else
用于多个条件判断,依次检查条件,直到匹配或执行默认分支。

if (条件1) {
// 条件1为true时执行
} else if (条件2) {
// 条件2为true时执行
} else {
// 所有条件都不匹配时执行
}
AI写代码
java
运行
示例:根据分数划分等级。
int score = 85;
char grade;
if (score >= 90) {
grade = ‘A’;
} else if (score >= 80) {
grade = ‘B’;
} else if (score >= 70) {
grade = ‘C’;
} else if (score >= 60) {
grade = ‘D’;
} else {
grade = ‘F’;
}
System.out.println(“等级: “ + grade);
AI写代码
java
运行

  1. switch语句
    switch语句用于基于表达式的值匹配多个固定选项。它比if-else if更简洁,适用于离散值比较。语法包括case分支和可选的default分支,每个分支后需加break以防止“穿透”。

基本语法
switch (表达式) {
case 值1:
// 当表达式等于值1时执行
break;
case 值2:
// 当表达式等于值2时执行
break;
default:
// 都不匹配时执行
break;
}
AI写代码
java
运行

完整示例
以下代码演示了根据数字输出星期几:

public class SwitchDemo {
public static void main(String[] args) {
int day = 3;
switch (day) {
case 1:
System.out.println(“星期一”);
break;
case 2:
System.out.println(“星期二”);
break;
case 3:
System.out.println(“星期三”);
break;
case 4:
System.out.println(“星期四”);
break;
case 5:
System.out.println(“星期五”);
break;
case 6:
System.out.println(“星期六”);
break;
case 7:
System.out.println(“星期日”);
break;
default:
System.out.println(“输入错误,请输入1-7”);
break;
}
}
}
AI写代码
java
运行

运行结果:当day = 3时,输出星期三。
注意:break语句是必须的,否则会继续执行后续case分支。
3. if vs switch:使用建议
使用if的情况:当条件涉及范围比较(如分数区间)、复杂布尔逻辑或非离散值时。例如,if (score >= 90)适合用if。
使用switch的情况:当基于单个表达式的离散值匹配时(如枚举、整数或字符串)。例如,switch (day)适合用switch。
性能:在Java中,switch通常编译为更高效的跳转表,适合大量case分支;if更灵活但可能稍慢。
最佳实践:确保代码可读性,避免嵌套过深。如果需要处理多个相关条件,优先考虑switch。

注意: 在Java中,switch语句如果没有使用break关键字,会导致“fall-through”(穿透)行为,即匹配到一个case后,会继续执行后续所有case中的代码,直到遇到break或switch结束。的代码示例。

代码演示(没有break的情况)
int num = 2;
switch (num) {
case 1:
System.out.print(“A”);
case 2:
System.out.print(“B”); // 执行这个
case 3:
System.out.print(“C”); // 还会继续执行这个!
case 4:
System.out.print(“D”); // 还会继续执行这个!
}
AI写代码
java
运行

行为解释
变量初始化:num被赋值为2。
switch匹配:由于num的值是2,程序会匹配到case 2。
执行并fall-through:
首先执行case 2中的语句,打印”B”。
由于没有break语句,程序不会退出switch,而是继续执行后续case(case 3和case 4),打印”C”和”D”。
输出结果:最终输出是”BCD”,因为打印操作依次是”B”、”C”、”D”。
输出验证
运行此代码,控制台输出结果为:
BCD

建议
在实际编程中,为了避免意外行为,通常在每个case后添加break语句来终止执行。例如:

switch (num) {
case 1:
System.out.print(“A”);
break; // 添加break以退出switch
// …其他case类似
}
AI写代码
java
运行
这样可以确保只执行匹配的case代码块。

3.2 循环语句

for循环
for循环适用于已知迭代次数的场景,包含初始化、循环条件和更新三部分。

// 语法格式
for (初始化; 循环条件; 更新) {
// 循环体
}

// 示例:打印1到10
for (int i = 1; i <= 10; i++) {
System.out.print(i + “ “);
}
// 输出:1 2 3 4 5 6 7 8 9 10
AI写代码
java
运行

while循环
while循环在条件为真时重复执行代码块,适合不确定迭代次数的情况。

// 语法格式
while (循环条件) {
// 循环体
}

// 示例:打印1到10
int i = 1;
while (i <= 10) {
System.out.print(i + “ “);
i++;
}
AI写代码
java
运行

do-while循环(至少执行一次)
do-while循环先执行一次循环体,再检查条件,确保代码块至少运行一次。

// 语法格式
do {
// 循环体(至少执行一次)
} while (循环条件);

// 示例:打印1到10
int i = 1;
do {
System.out.print(i + “ “);
i++;
} while (i <= 10);
AI写代码
java
运行

三种循环的区别

循环类型 执行特点 适用场景
for 先判断,后执行 知道循环次数
while 先判断,后执行 不知道循环次数
do-while 先执行,后判断 至少执行一次
3.3 跳转语句

语句 作用
break 用于循环或switch结构中,立即退出当前结构。
continue 跳过本次循环剩余代码,进入下一次循环
return 在方法或函数中,终止执行并可选返回一个值;如果无返回值,则单纯结束方法。

  1. break关键字的作用
    break用于立即终止整个循环,跳出循环体。当满足特定条件时,循环会提前结束,不再执行后续迭代。

代码示例
// break示例:遇到7就停止
for (int i = 1; i <= 10; i++) {
if (i == 7) {
break; // 循环到7就结束
}
System.out.print(i + “ “);
}
// 输出:1 2 3 4 5 6
AI写代码
java
运行
解释
循环从1迭代到10。
当i等于7时,break语句被执行,整个循环立即终止。
因此,输出只显示1到6,而7及之后的数字未被打印。
2. continue关键字的作用
continue用于跳过当前迭代的剩余代码,直接进入下一次迭代。循环不会终止,而是继续执行后续的迭代。

代码示例
// continue示例:跳过7
for (int i = 1; i <= 10; i++) {
if (i == 7) {
continue; // 跳过7,继续后面的
}
System.out.print(i + “ “);
}
// 输出:1 2 3 4 5 6 8 9 10
AI写代码
java
运行
解释
循环从1迭代到10。
当i等于7时,continue语句被执行,跳过本次迭代的打印操作。
循环继续执行,输出1到6和8到10,唯独跳过7。
3. break与continue的对比
关键字 行为 适用场景
break 立即终止整个循环 当检测到满足退出条件(如找到目标值)时
continue 跳过当前迭代,继续下一次迭代 当需要忽略某些特定值(如无效输入)时
核心区别
break:完全退出循环,适用于提前结束任务。
continue:仅跳过当前步骤,适用于过滤部分数据。
四、代码示例

示例1:判断闰年
此代码通过条件判断年份是否为闰年。规则为:年份能被4整除但不能被100整除,或者能被400整除。

public class LeapYear {
public static void main(String[] args) {
int year = 2024;
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
System.out.println(year + “年是闰年”);
} else {
System.out.println(year + “年是平年”);
}
}
}
AI写代码
java
运行

示例2:简单的计算器
此代码实现一个基本计算器,支持加、减、乘、除操作。除法时检查除数是否为0,避免错误。

public class Calculator {
public static void main(String[] args) {
double a = 10;
double b = 3;
char operator = ‘/‘;
double result;

switch (operator) {
  case '+':
    result = a + b;
    break;
  case '-':
    result = a - b;
    break;
  case '*':
    result = a * b;
    break;
  case '/':
    if (b != 0) {
      result = a / b;
    } else {
      System.out.println("除数不能为0!");
      return;
    }
    break;
  default:
    System.out.println("不支持的运算符");
    return;
}
System.out.println(a + " " + operator + " " + b + " = " + result);

}
}
AI写代码
java
运行

示例3:打印九九乘法表
此代码使用嵌套循环打印九九乘法表,输出格式整齐。

public class MultiplicationTable {
public static void main(String[] args) {
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
System.out.print(j + “×” + i + “=” + (i * j) + “\t”);
}
System.out.println(); // 换行
}
}
}
// 输出:标准的九九乘法表
AI写代码
java
运行

示例4:计算1到100的和
此代码演示三种方式计算1到100的和:for循环、while循环和数学公式验证。公式:和 𝑆=(首项+末项)×÷2,首项 𝑎1=1,末项 𝑎𝑛=100,项数 𝑛=100。

public class SumExample {
public static void main(String[] args) {
// for循环实现
int sum1 = 0;
for (int i = 1; i <= 100; i++) {
sum1 += i;
}
System.out.println(“for循环结果:” + sum1);

// while循环实现
int sum2 = 0;
int j = 1;
while (j <= 100) {
  sum2 += j;
  j++;
}
System.out.println("while循环结果:" + sum2);

// 数学公式验证:和 = (首项+末项)×项数÷2 = (1+100)×100÷2 = 5050
System.out.println("验证结果:5050");

}
}
AI写代码
java
运行

五、常见错误与注意点

错误写法 正确写法 说明
if (a = 5) if (a == 5) 判断相等用==,单等号是赋值
switch (x) { case 1.5: } case后面必须是整数、字符或枚举常量 switch不支持小数
for (int i=0; i<10; i++); 去掉分号 分号会让循环体变成空语句
while (true); 确保有break或条件是假的 会变成死循环
5 / 2 期望得2.5 5.0 / 2 或 5 / 2.0 整数除法会丢失小数
忘记写break 写上break 会导致switch穿透
六、小结

今天学会了:

  • 各种运算符的使用(算术、关系、逻辑、赋值、位运算)
  • 运算符优先级和instanceof运算符
  • if-else分支结构
  • switch语句及穿透现象
  • 三种循环(for、while、do-while)
  • break、continue、return跳转语句

核心要点:

  1. =是赋值,==是判断相等
  2. &&和||有短路特性
  3. switch中忘记break会导致穿透
  4. 整数除法会丢失小数部分
  5. 循环变量要确保能退出循环,避免死循环

Java学习笔记(二):基本数据类型、数组与枚举

一、今日学习内容
今天学习了第二章,主要内容包括:

  1. 标识符与关键字
  2. 8种基本数据类型
  3. 数据类型转换
  4. 数组的声明、创建和遍历
  5. 枚举类型

二、重点知识整理

2.1 标识符命名规则
由字母、数字、下划线 _、美元符号 $ 组成
不能以数字开头
不能是Java关键字(如 public、class、int)
区分大小写
命名规范:类名首字母大写(驼峰命名),变量名首字母小写(驼峰命名)

2.2 8种基本数据类型(重点!)

|        类型       | 关键字    | 占用字节 |     取值范围         |  默认值  |
|       字节型     |    byte    |         1      |     -128 ~ 127      |      0      |
|      短整型      |   short    |         2      |  -32768 ~ 32767 |     0       |
|         整型       |      int     |        4       |        约 ±21亿      |     0       |
|       长整型     |    long     |        8      |           很大          |     0L      |
| 单精度浮点型 |   float     |        4       |    约 ±3.4e38      |   0.0f     |
| 双精度浮点型 |  double  |        8       |    约 ±1.8e308    |    0.0     |
|        字符型     |     char   |        2       |      0 ~ 65535     | ‘\u0000’ |
|        布尔型     | boolean | 1(概念上) |     true / false     |    false   |

记忆 口诀:byte short int long,float double char boolean

2.3 注意事项

  1. long类型数值后面要加L
    long distance = 12345678900L;
  2. float类型数值后面要加f
    float price = 19.99f;
  3. char用单引号,String用双引号
    char grade = ‘A’;
    String name = “张三”;
  4. 布尔值只能是true或false,不能用0或1代替
    boolean isPass = true;   // 对
    boolean isFail = false;  // 对
    // boolean isOk = 1;     //  错误!

2.4 数据类型转换
自动类型转换(小→大):byte → short → int → long → float → double
java
int a = 100; double b = a; // 自动转换,b = 100.0
强制类型转换(大→小):需要手动写 (类型)
java
double x = 3.14; int y = (int)x; // 强制转换,y = 3(小数部分丢失)
2.5 数组

声明数组
java
int[] scores;      // 推荐写法
int scores[];      // 也可以,但不推荐

创建数组
java
// 方式1:先声明后创建
int[] scores;
scores = new int[5];
// 方式2:声明并创建
int[] scores = new int[5];
// 方式3:声明并初始化
int[] scores = {90, 85, 78, 92, 88};

遍历数组
java
int[] arr = {10, 20, 30, 40, 50}; // 普通for循环 
for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } // 增强for循环(foreach) 
for (int num : arr) { System.out.println(num); }

数组的 length 属性可以获取数组长度,注意是属性不是方法,没有括号。

2.6 枚举类型
枚举用于定义一组常量,比如星期、季节、方向等。
java
// 定义枚举
enum Weekday {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
enum Season {
    春, 夏, 秋, 冬   // 可以使用中文
}
// 使用枚举
public class EnumDemo {
    public static void main(String[] args) {
        Weekday today = Weekday.MONDAY;
        Season current = 秋;
        System.out.println(“今天是:” + today);
        System.out.println(“当前季节:” + current);
        // 遍历枚举
        for (Season s : Season.values()) {
            System.out.println(s);
        }
    }
}
三、代码示例
示例1:计算平均分
java
public class ScoreAverage {
    public static void main (String[] args) {
        int[] scores = {85, 90, 78, 92, 88};
        int sum = 0;
        for (int i = 0; i < scores.length; i++) {
            sum = sum + scores[i];
        }       
        double average = (double)sum / scores.length;
        System.out.println(“总分:” + sum);
        System.out.println(“平均分:” + average);
    }
}
示例2:使用枚举表示一周计划
java
enum Weekday {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
public class WeeklyPlan {
    public static void main(String[] args) {
        Weekday today = Weekday.MONDAY;    
        switch (today) {
            case MONDAY:
                System.out.println(“周一:学习Java第一章”);
                break;
            case TUESDAY:
                System.out.println(“周二:学习Java第二章”);
                break;
            // … 其他日子
            default:
                System.out.println(“周末:休息”);
        }
    }
}
四、常见错误与注意点 
|         错误写法        |             正确写法          |                         说明                       |
|int a[] = new int(5);  |    int[] a = new int[5];    |     数组用方括号,不是圆括号       |
|String str = ‘hello’;   |    String str = “hello”;    |     String用双引号,char用单引号  |
|      float f = 3.14;     |       float f = 3.14f;        |            float后面要加f                      |
|      int x = 3.14;       |      int x = (int)3.14;      |           大转小要强制转换                 |
|     arr.length()         |          arr.length            |    数组的length是属性,不是方法   |
五、小结
今天学会了:
8种基本数据类型的取值范围和默认值
自动类型转换和强制类型转换
数组的声明、创建和三种遍历方式
枚举的定义和使用
核心:
int是默认的整数类型,double是默认的小数类型
数组下标从0开始,最大下标 = length - 1
枚举可以把一组常量组织在一起,让代码更清晰

Java学习笔记(一):Java语言入门与开发环境搭建

一、今日学习内容

今天学习了《Java面向对象程序设计(第4版)》第一章,主要内容包括:

  1. Java语言的历史与特点
  2. JDK的安装与环境变量配置
  3. 第一个Java程序:HelloWorld
  4. Java程序的编译与运行过程
  5. Java编程风格(Allmans风格和Kernighan风格)

二、重点知识整理

2.1 Java是什么?

Java是Sun公司(现被Oracle收购)于1995年推出的一门面向对象的编程语言,具有 “一次编写,到处运行”的特点。

2.2 Java的三个版本

| 版本 | 全称 | 用途 |
| Java SE | Java Standard Edition | 标准版,桌面应用开发,是学习的基础 |
| Java EE | Java Enterprise Edition | 企业版,Web开发、企业级应用 |
| Java ME | Java Micro Edition | 微型版,嵌入式设备(如旧式手机) |

2.3 JDK、JRE、JVM的关系

JDK(Java Development Kit):Java开发工具包,给程序员用的,包含JRE和开发工具
JRE(Java Runtime Environment):Java运行环境,给普通用户用的,包含JVM
JVM(Java Virtual Machine):Java虚拟机,实现跨平台的核心
关系:JDK > JRE > JVM

2.4 环境变量配置(重要!)

安装JDK后,需要配置两个环境变量:

| 变量名 | 变量值 | 作用 |
| JAVA_HOM | JDK安装路径(如 C:\Program Files\Java\jdk-11| 方便其他软件找到JDK |
| Path | 添加 %JAVA_HOME%\bin |让命令行能找到java和javac命令 |
验证是否配置成功:打开命令行输入 java -version ,看到版本信息即成功。

2.5 第一个Java程序

Hello.java
public class Hello {
public static void main(String[] args) {
System.out.println(“这是一个简单的java应用程序”);
Student stu=new Student();
stu.speak(“We are students”);
}
}
class Student{
public void speak(String s) {
system.out.println(s);
}
}

2.6 编译与运行步骤

  1. 编写源码:用记事本编写,保存为 Hello.java(文件名必须与类名相同)
  2. 编译:javac Hello.java(生成 Hello.class 字节码文件)
  3. 运行:java Hello(JVM解释执行字节码)
    注意:运行命令是 java Hello,不加 .class 后缀!

2.7 Java的两种编程风格

本书介绍了两种代码缩进风格:
Allmans风格(独行风格):左大括号单独占一行
java
class Allmans
{
public static void main(String args[])
{
int sum=0,i=0,j=0;
for(i=1;i<=100;i++)
{
sum=sum+i;
}
System.out.println(sum);
}
}

Kernighan风格(行尾风格):左大括号在上一行末尾
java
class Kernighan{
public static void main(String[] args) {
int sum=0;i=0,j=0;
for(i=1;i<=1000;i++){
sum=sum+i;
}
System.out.println(sum);
}
}
本书采用Kernighan风格,这也是大多数Java程序员使用的风格。

三、遇到的问题与解决方法

1.javac 不是内部或外部命令:Path没配置好(检查Path中是否添加了 %JAVA_HOME%\bin)
2.错误: 找不到或无法加载主类:运行命令写错了(应该是 java Hello,不是 java Hello.class)
3.类Hello是公共的,应在名为Hello.java的文件中声明:文件名与类名不一致(把文件名改成 Hello.java)

四、小结

今天学会了:
1.Java语言的特点(跨平台、面向对象)
2.JDK的安装和环境变量配置
3.写第一个Java程序并成功运行
4.区分两种代码风格

  • Copyrights © 2026 Shipanxs
  • 访问人数: | 浏览次数:

如果这篇文章对你有帮助,可以请我喝杯茶

支付宝

支付宝扫一扫