当前位置: 首页 > news >正文

# JavaSE核心知识点02面向对象编程

🤟致敬读者

  • 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉

📘博主相关

  • 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息

文章目录

  • JavaSE核心知识点02面向对象编程
    • JavaSE核心知识点02面向对象编程02-01(类与对象)
      • **一、类(Class):设计蓝图**
        • 1. **什么是类?**
        • 2. **如何定义一个类?**
      • **二、对象(Object):类的实例**
        • 1. **什么是对象?**
        • 2. **如何创建对象?**
      • **三、实例变量 vs 静态变量**
        • 1. **实例变量(对象级别)**
        • 2. **静态变量(类级别)**
      • **四、封装(Encapsulation)**
        • 1. **为什么要封装?**
        • 2. **实现封装的步骤:**
      • **五、构造方法(Constructor)**
        • 1. **什么是构造方法?**
        • 2. **默认构造方法**
        • 3. **自定义构造方法**
      • **六、继承(Inheritance)**
      • **七、对象的内存分配**
      • **八、常见误区**
      • **九、最佳实践**
      • **十、练习题目**
    • JavaSE核心知识点02面向对象编程02-02(封装、继承、多态)
    • **一、封装(Encapsulation)**
      • **1. 什么是封装?**
      • **2. 如何实现封装?**
      • **3. 代码示例**
      • **4. 封装的好处**
    • **二、继承(Inheritance)**
      • **1. 什么是继承?**
      • **2. 代码示例**
      • **3. 继承的注意事项**
    • **三、多态(Polymorphism)**
      • **1. 什么是多态?**
      • **2. 方法重写(Override)**
      • **3. 向上转型(Upcasting)**
      • **4. 多态的优势**
    • **四、总结与对比**
    • **五、常见问题**
      • **1. 方法重载(Overload) vs 方法重写(Override)**
      • **2. 什么时候用继承?**
    • JavaSE核心知识点02面向对象编程02-03(抽象类与接口)
    • 一、抽象类(Abstract Class)
      • **1. 什么是抽象类?**
      • **2. 抽象方法**
      • **3. 继承抽象类**
      • **4. 使用场景**
    • 二、接口(Interface)
      • **1. 什么是接口?**
      • **2. 定义接口**
      • **3. 实现接口**
      • **4. 多实现**
      • **5. 使用场景**
    • 三、抽象类 vs 接口:核心区别
    • 四、如何选择抽象类 vs 接口?
      • **1. 用抽象类的情况**
      • **2. 用接口的情况**
    • 五、实际案例
      • **场景**:设计一个游戏中的角色系统
    • 六、常见误区
    • 七、总结
    • JavaSE核心知识点02面向对象编程02-04(包和导入)
      • **一、包(Package)的作用**
      • **二、定义包**
      • **三、导入(Import)其他包的类**
      • **四、常见场景与注意事项**
        • **1. 同一包内的类无需导入**
        • **2. 不同包中的类必须导入**
        • **3. 处理同名类冲突**
      • **五、默认包(不推荐使用)**
      • **六、包与访问权限**
      • **七、实战练习**
      • **八、常见问题解答**
    • JavaSE核心知识点02面向对象编程02-05(方法)
      • **一、方法是什么?**
      • **二、方法的组成**
      • **三、如何定义方法?**
        • **1. 无参数、无返回值的方法**
        • **2. 带参数、有返回值的方法**
        • **3. 多个参数的方法**
      • **四、如何调用方法?**
        • **1. 调用静态方法(`static`修饰)**
        • **2. 调用非静态方法(需要对象实例)**
      • **五、方法的重载(Overload)**
      • **六、递归方法(Recursion)**
      • **七、常见问题解答**
        • **1. 方法是否需要返回值?**
        • **2. 参数传递是“值传递”还是“引用传递”?**
        • **3. 静态方法 vs 非静态方法?**
      • **八、总结与练习**
    • JavaSE核心知识点02面向对象编程02-06(泛型)
      • **一、为什么需要泛型?**
      • **二、泛型的基本语法**
        • **1. 定义泛型类/接口**
        • **2. 使用泛型类**
      • **三、泛型方法**
      • **四、泛型通配符 `?`**
        • **1. 无界通配符 `<?>`**
        • **2. 上界通配符 `<? extends T>`**
        • **3. 下界通配符 `<? super T>`**
        • **PECS 原则**(Producer Extends, Consumer Super)
      • **五、类型擦除(Type Erasure)**
      • **六、泛型的限制与注意事项**
      • **七、典型应用场景**
      • **八、代码示例:自定义泛型栈**
      • **九、总结**
    • JavaSE核心知识点02面向对象编程02-07(枚举)
      • **一、泛型存在的意义**
      • **二、泛型核心语法**
      • **三、类型通配符**
      • **四、类型擦除与限制**
      • **五、泛型高级应用**
      • **六、最佳实践与常见错误**
      • **七、学习建议**
    • JavaSE核心知识点02面向对象编程02-8(异常处理)
      • **一、异常处理的核心概念**
        • **1. 什么是异常?**
        • **2. Java异常分类**
      • **二、异常处理的关键字**
        • **1. try-catch-finally**
        • **2. throws**
        • **3. throw**
      • **三、常见异常类型与处理**
        • **1. 常见异常示例**
        • **2. 处理多个异常**
      • **四、自定义异常**
        • **1. 创建自定义异常类**
        • **2. 使用自定义异常**
      • **五、最佳实践与常见陷阱**
        • **1. 最佳实践**
        • **2. 常见陷阱**
      • **六、总结与练习**
        • **1. 关键点总结**
        • **2. 练习题目**


📃文章前言

  • 🔷文章均为学习工作中整理的笔记。
  • 🔶如有错误请指正,共同学习进步。

JavaSE核心知识点02面向对象编程

JavaSE核心知识点02面向对象编程02-01(类与对象)

**类(Class)对象(Object)**是面向对象编程(OOP)的核心基础。以下用通俗易懂的方式,结合代码示例和生活中的例子,帮你彻底掌握它们!


一、类(Class):设计蓝图

1. 什么是类?
  • 是对象的模板或蓝图,定义了对象的属性(数据)行为(方法)
  • 例如:设计一辆汽车前,你需要图纸(类),图纸规定了汽车的品牌、颜色(属性)和启动、刹车(方法)。
2. 如何定义一个类?
public class Dog {// 成员变量(属性)String name;int age;// 方法(行为)void bark() {System.out.println(name + "汪汪叫!");}
}
  • 成员变量:描述对象的属性(如name, age)。
  • 方法:描述对象能做什么(如bark())。

二、对象(Object):类的实例

1. 什么是对象?
  • 对象是根据类创建的具体实例,占用内存空间。
  • 例如:根据Dog类可以创建具体的狗对象(如“小黑,3岁”)。
2. 如何创建对象?
public class Main {public static void main(String[] args) {// 创建Dog类的对象Dog myDog = new Dog();// 设置对象的属性myDog.name = "小黑";myDog.age = 3;// 调用对象的方法myDog.bark();  // 输出:小黑汪汪叫!}
}
  • new关键字:在内存中分配空间,创建对象。
  • .操作符:访问对象的属性和方法。

三、实例变量 vs 静态变量

1. 实例变量(对象级别)
  • 每个对象拥有独立的副本。
  • 例如:每只狗的nameage不同。
2. 静态变量(类级别)
  • static修饰,所有对象共享同一份数据。
  • 例如:统计所有狗的数量。
public class Dog {String name;int age;static int totalDogs = 0;  // 静态变量public Dog() {totalDogs++;  // 每创建一只狗,总数+1}
}// 使用:
Dog dog1 = new Dog();
Dog dog2 = new Dog();
System.out.println(Dog.totalDogs);  // 输出2(通过类名访问)

四、封装(Encapsulation)

1. 为什么要封装?
  • 保护数据,防止外部直接修改。
  • 例如:狗的年龄不能为负数,通过方法控制。
2. 实现封装的步骤:
  1. 私有化成员变量:用private修饰。
  2. 提供公共方法gettersetter
public class Dog {private String name;private int age;// Getter方法(读取属性)public String getName() {return name;}// Setter方法(设置属性)public void setAge(int age) {if (age >= 0) {  // 校验合法性this.age = age;} else {System.out.println("年龄不能为负数!");}}
}// 使用:
Dog dog = new Dog();
dog.setAge(-1);  // 输出:年龄不能为负数!

五、构造方法(Constructor)

1. 什么是构造方法?
  • 用于初始化对象,在new时自动调用。
  • 方法名与类名相同,没有返回类型。
2. 默认构造方法
  • 如果类中没有定义构造方法,Java会提供默认的无参构造方法。
  • 例如:Dog dog = new Dog();
3. 自定义构造方法
public class Dog {private String name;private int age;// 自定义构造方法public Dog(String name, int age) {this.name = name;this.age = age;}
}// 使用:
Dog myDog = new Dog("小黑", 3);  // 直接初始化属性

六、继承(Inheritance)

(先简单了解,后续可深入学习)

  • 子类继承父类的属性和方法,实现代码复用。
public class Animal {  // 父类void eat() {System.out.println("动物吃东西");}
}public class Dog extends Animal {  // 子类void bark() {System.out.println("狗叫");}
}// 使用:
Dog dog = new Dog();
dog.eat();  // 继承自Animal类

七、对象的内存分配

  • 栈内存:存储对象的引用变量(如Dog myDog)。
  • 堆内存:存储实际对象的数据(通过new分配)。
Dog dog1 = new Dog();  // dog1引用指向堆中的对象
Dog dog2 = dog1;       // dog2和dog1指向同一个对象

八、常见误区

  1. 混淆类和对象

    • 类:Dog(设计图)。
    • 对象:new Dog()(具体的狗)。
  2. 误用静态变量

    • 静态变量属于类,不要通过对象访问(用类名.变量名)。

九、最佳实践

  1. 单一职责原则:一个类只做一件事。
  2. 合理封装:尽量将成员变量设为private
  3. 优先使用实例变量:除非需要共享数据,否则不用static

十、练习题目

  1. 定义一个Student类,包含姓名、学号、年龄属性,并提供方法打印学生信息。
  2. 创建一个BankAccount类,实现存款、取款、查询余额功能,并保证余额不被直接修改。

通过以上内容,你已经掌握了Java类与对象的核心概念!接下来可以尝试编写小项目(如学生管理系统),巩固知识!如果有疑问,随时问我哦 😊


JavaSE核心知识点02面向对象编程02-02(封装、继承、多态)

封装、继承和多态是面向对象编程(OOP)的三大核心特性,理解它们对掌握Java至关重要。我会用通俗易懂的方式为你讲解,并结合代码示例帮助你理解。


一、封装(Encapsulation)

1. 什么是封装?

  • 定义:将数据(属性)和操作数据的方法(行为)捆绑在一个类中,并对外隐藏内部实现细节。
  • 核心思想:隐藏对象的属性和实现细节,仅对外公开接口(方法)进行交互。
  • 目的:提高安全性、可维护性、灵活性(例如:避免属性被随意修改)。

2. 如何实现封装?

  • 使用访问修饰符控制属性的可见性:
    • private:属性只能在当前类内访问。
    • public:属性或方法可以被任何类访问。
    • protected:允许子类和同包类访问。
  • 提供公共的getter和setter方法操作属性。

3. 代码示例

public class Student {// 私有属性,外部无法直接访问private String name;private int age;// 公共的getter方法,允许外部获取属性值public String getName() {return name;}// 公共的setter方法,允许外部设置属性值(可添加校验逻辑)public void setName(String name) {if (name != null && !name.isEmpty()) {this.name = name;}}public int getAge() {return age;}public void setAge(int age) {if (age >= 0 && age <= 120) {  // 校验年龄合法性this.age = age;}}
}// 使用示例
public class Main {public static void main(String[] args) {Student stu = new Student();stu.setName("Alice");stu.setAge(20);System.out.println(stu.getName() + ": " + stu.getAge());}
}

4. 封装的好处

  • 安全性:防止属性被非法修改(如年龄为负数)。
  • 灵活性:可以在setter方法中添加校验逻辑,而外部调用者无需关心。
  • 代码维护:修改类的内部实现时,不影响外部代码。

二、继承(Inheritance)

1. 什么是继承?

  • 定义:子类(派生类)继承父类(基类)的属性和方法,并可以扩展自己的功能。
  • 核心思想:代码复用 + 扩展功能。
  • 语法:使用 extends 关键字。

2. 代码示例

// 父类:Animal
class Animal {private String name;public void eat() {System.out.println(name + " is eating.");}public void setName(String name) {this.name = name;}
}// 子类:Dog(继承Animal)
class Dog extends Animal {// 扩展自己的方法public void bark() {System.out.println("Woof! Woof!");}
}// 使用示例
public class Main {public static void main(String[] args) {Dog dog = new Dog();dog.setName("Buddy");dog.eat();   // 调用父类方法dog.bark();  // 调用子类方法}
}

3. 继承的注意事项

  • 单继承:Java中一个类只能直接继承一个父类(不支持多继承)。
  • 构造方法:子类构造方法默认会调用父类的无参构造方法(可通过 super() 显式调用父类构造方法)。
  • 方法重写(Override):子类可以重写父类的方法(后面多态中详细讲解)。

三、多态(Polymorphism)

1. 什么是多态?

  • 定义:同一操作作用于不同对象,可以有不同的行为(例如:同一方法在不同子类中有不同实现)。
  • 两种形式
    1. 编译时多态(静态多态):方法重载(Overload)。
    2. 运行时多态(动态多态):方法重写(Override) + 向上转型(Upcasting)。

2. 方法重写(Override)

  • 子类重新定义父类中已有的方法。
  • 规则
    • 方法名、参数列表必须与父类方法相同。
    • 返回类型可以是父类方法返回类型的子类。
    • 访问权限不能比父类方法更严格。
class Animal {public void makeSound() {System.out.println("Animal makes a sound");}
}class Dog extends Animal {@Override  // 注解:表示重写父类方法public void makeSound() {System.out.println("Dog barks: Woof!");}
}class Cat extends Animal {@Overridepublic void makeSound() {System.out.println("Cat meows: Meow~");}
}

3. 向上转型(Upcasting)

  • 将子类对象赋值给父类引用变量。
  • 目的:通过父类引用调用子类重写的方法,实现多态。
public class Main {public static void main(String[] args) {Animal animal1 = new Dog();  // 向上转型Animal animal2 = new Cat();animal1.makeSound();  // 输出 Dog barks: Woof!animal2.makeSound();  // 输出 Cat meows: Meow~}
}

4. 多态的优势

  • 代码扩展性:新增子类时无需修改原有代码。
  • 统一接口:用父类引用处理不同子类对象。

四、总结与对比

特性核心思想关键实现方式
封装隐藏细节,暴露接口private属性 + getter/setter
继承代码复用,扩展功能extends关键字 + 方法重写
多态同一方法不同表现方法重写 + 向上转型

五、常见问题

1. 方法重载(Overload) vs 方法重写(Override)

  • 重载:同一类中,方法名相同,参数列表不同。
  • 重写:子类中重新实现父类方法。

2. 什么时候用继承?

  • 符合 “is-a” 关系时(例如:Dog is a Animal)。
  • 避免过度继承(优先考虑组合而非继承)。

通过这三个特性,你可以设计出灵活、可维护的Java程序。建议结合代码实践,尝试自己编写一些类,体会它们之间的关系!


JavaSE核心知识点02面向对象编程02-03(抽象类与接口)

作为Java面向对象编程的两个核心概念,抽象类接口是代码设计中非常重要的工具。下面我会从基础概念到实际应用,用简单易懂的方式为你详细讲解它们的区别和使用场景。


一、抽象类(Abstract Class)

1. 什么是抽象类?

  • 定义:用 abstract 关键字修饰的类,不能被实例化(不能直接 new)。
  • 核心作用:为子类提供公共模板,强制子类实现某些方法。
  • 特点
    • 可以包含普通方法(有方法体)和抽象方法(无方法体)。
    • 可以有成员变量构造方法静态方法等。
    • 单继承:一个类只能继承一个抽象类。

2. 抽象方法

  • 定义:用 abstract 修饰的方法,没有方法体,必须由子类实现。
    public abstract class Animal {// 抽象方法:没有方法体public abstract void eat();// 普通方法public void sleep() {System.out.println("动物在睡觉");}
    }
    

3. 继承抽象类

  • 子类必须实现所有抽象方法,否则子类也必须声明为 abstract
    public class Cat extends Animal {@Overridepublic void eat() {System.out.println("猫吃鱼");}
    }
    

4. 使用场景

  • 代码复用:多个子类有共同的代码逻辑(如 sleep() 方法)。
  • 强制规范:要求子类必须实现某些功能(如 eat() 方法)。

二、接口(Interface)

1. 什么是接口?

  • 定义:用 interface 关键字定义,表示一组行为规范
  • 核心作用:定义类能做什么(能力),而不是是什么(类型)。
  • 特点
    • 默认方法:Java 8+ 允许接口包含 default 方法(有方法体)。
    • 静态方法:Java 8+ 允许接口包含 static 方法。
    • 多实现:一个类可以实现多个接口。
    • 没有构造方法,不能实例化。
    • 成员变量默认是 public static final(常量)。

2. 定义接口

public interface Flyable {// 抽象方法(默认是 public abstract)void fly();// Java 8+ 默认方法default void land() {System.out.println("正在着陆");}// Java 8+ 静态方法static void checkAltitude() {System.out.println("检查飞行高度");}
}

3. 实现接口

  • 使用 implements 关键字,必须实现所有抽象方法。
    public class Bird implements Flyable {@Overridepublic void fly() {System.out.println("鸟在飞");}
    }
    

4. 多实现

  • 一个类可以实现多个接口,解决Java单继承的局限性。
    public class SuperDrone implements Flyable, Chargeable {// 实现所有接口的抽象方法
    }
    

5. 使用场景

  • 定义行为:比如 Flyable(可飞)、Swimmable(可游泳)。
  • 解耦代码:通过接口隔离不同模块的依赖。
  • 多态性:通过接口类型引用对象,提高灵活性。

三、抽象类 vs 接口:核心区别

特性抽象类接口
继承/实现单继承(extends)多实现(implements)
方法可以有抽象方法和具体方法Java 8前只有抽象方法,现在可以有默认方法和静态方法
成员变量可以是普通变量默认是 public static final(常量)
构造方法有构造方法无构造方法
设计目的表示“是什么”(is-a关系)表示“能做什么”(has-a能力)
使用场景代码复用 + 部分规范完全规范 + 行为扩展

四、如何选择抽象类 vs 接口?

1. 用抽象类的情况

  • 多个子类有共同的属性和方法需要复用。
  • 需要定义非 public 的成员非静态方法
  • 需要定义构造方法初始化状态。

2. 用接口的情况

  • 需要定义一组行为规范(如不同设备的功能)。
  • 需要实现多继承(一个类实现多个接口)。
  • 希望解耦代码,提高扩展性。

五、实际案例

场景:设计一个游戏中的角色系统

  • 抽象类Character(角色),定义公共属性(如生命值、位置)和方法(如移动)。
  • 接口Attackable(可攻击)、Defendable(可防御),定义不同角色的能力。
// 抽象类:角色基类
public abstract class Character {protected int health;protected int x, y;public Character(int health) {this.health = health;}public abstract void move();  // 抽象方法:移动方式由子类实现public void takeDamage(int damage) {health -= damage;}
}// 接口:可攻击
public interface Attackable {void attack(Character target);
}// 接口:可防御
public interface Defendable {void defend();
}// 具体类:战士
public class Warrior extends Character implements Attackable, Defendable {public Warrior() {super(100);}@Overridepublic void move() {System.out.println("战士步行移动");}@Overridepublic void attack(Character target) {System.out.println("战士用剑攻击");target.takeDamage(20);}@Overridepublic void defend() {System.out.println("战士举盾防御");}
}

六、常见误区

  1. 滥用继承:如果不需要复用代码,优先用接口。
  2. 过度设计:不要为了用抽象类而用,根据需求选择。
  3. 忽略默认方法:Java 8+ 的接口可以通过 default 方法提供默认实现,减少代码重复。

七、总结

  • 抽象类是什么(is-a),适合代码复用 + 部分规范。
  • 接口能做什么(has-a),适合定义行为 + 多态扩展。

掌握两者的区别和适用场景,能帮助你写出更灵活、可维护的代码!如果还有疑问,可以尝试写几个小例子练习一下~ 😊


JavaSE核心知识点02面向对象编程02-04(包和导入)

包(Package)和导入(Import)是 Java 中组织和管理代码的核心机制,尤其适合项目规模较大时的代码维护。以下是专门整理的详细指南,从基础到实践,逐步掌握它们的使用方法。


一、包(Package)的作用

  1. 避免命名冲突
    不同包中可以有同名的类,例如:com.company1.utils.StringUtilcom.company2.utils.StringUtil
  2. 组织代码结构
    按功能或模块分类类文件,例如:com.example.dao(数据库操作)、com.example.model(数据模型)。
  3. 控制访问权限
    Java 的访问修饰符(如 protected、默认权限)与包密切相关。

二、定义包

  1. 语法
    在 Java 文件的第一行使用 package 声明包:

    package com.example.util;  // 定义当前类属于 com.example.util 包
    
  2. 包命名规范

    • 全部小写,使用公司域名的倒序(如 com.example)。
    • 多层包名用 . 分隔,对应文件系统的目录结构(如 com/example/util)。
  3. 示例

    • 文件路径:src/com/example/util/StringUtil.java
    • 类定义:
      package com.example.util;  // 必须与目录结构一致!public class StringUtil {public static String trim(String str) {return str.trim();}
      }
      

三、导入(Import)其他包的类

  1. 为什么需要导入
    使用其他包中的类时,需要通过 import 引入,否则需写类的全限定名(Fully Qualified Name)。

  2. 导入单个类

    import java.util.ArrayList;  // 导入 ArrayListpublic class Main {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();}
    }
    
  3. 导入整个包
    使用通配符 * 导入包下所有类(不推荐,可能引发命名冲突):

    import java.util.*;  // 导入 java.util 包下的所有类
    
  4. 静态导入(Static Import)
    导入类的静态成员(方法或变量),可直接使用:

    import static java.lang.Math.PI;  // 导入 Math 类的 PI 常量public class Circle {double area(double radius) {return PI * radius * radius;  // 直接使用 PI,无需写 Math.PI}
    }
    

四、常见场景与注意事项

1. 同一包内的类无需导入
// 文件:com/example/Main.java
package com.example;public class Main {public static void main(String[] args) {User user = new User();  // User 类在同一个包 com.example 中,无需导入}
}// 文件:com/example/User.java
package com.example;public class User {// 类定义
}
2. 不同包中的类必须导入
// 文件:com/test/App.java
package com.test;import com.example.User;  // 导入其他包的类public class App {public static void main(String[] args) {User user = new User();}
}
3. 处理同名类冲突

如果两个包中有同名类,需用全限定名或只导入其中一个:

import java.util.Date;  // 导入 java.util.Datepublic class ConflictExample {public static void main(String[] args) {Date utilDate = new Date();  // java.util.Datejava.sql.Date sqlDate = new java.sql.Date(System.currentTimeMillis());  // 全限定名}
}

五、默认包(不推荐使用)

  • 如果不写 package 语句,类会放在默认包(无名包)。
  • 问题:默认包的类无法被其他包的类导入,且容易引发命名冲突。
  • 建议:始终为类指定明确的包名!

六、包与访问权限

  • public:所有包可见。
  • protected:同包或子类可见。
  • 默认(无修饰符):同包可见。
  • private:仅本类可见。
package com.example;public class Demo {public void publicMethod() {}     // 所有包可见protected void protectedMethod() {}  // 同包或子类可见void defaultMethod() {}           // 同包可见private void privateMethod() {}   // 仅本类可见
}

七、实战练习

  1. 创建包和类

    • 创建包 com.example.utils,在其中定义工具类 MathUtils
    • 在另一个包 com.example.app 中创建 Main 类,导入并使用 MathUtils
  2. 代码示例

    // 文件:com/example/utils/MathUtils.java
    package com.example.utils;public class MathUtils {public static int add(int a, int b) {return a + b;}
    }// 文件:com/example/app/Main.java
    package com.example.app;import com.example.utils.MathUtils;  // 导入工具类public class Main {public static void main(String[] args) {int sum = MathUtils.add(3, 5);System.out.println("Sum: " + sum);  // 输出 Sum: 8}
    }
    

八、常见问题解答

  1. IDE(如 IntelliJ IDEA)如何帮助管理包?

    • 自动生成包目录结构。
    • 自动提示导入缺失的类。
    • 优化导入(删除未使用的导入)。
  2. 导入会影响性能吗?

    • 不会!import 仅是编译时声明,不影响运行时性能。
  3. 为什么有时需要写全限定名?

    • 当两个导入的类同名时(如 java.util.Datejava.sql.Date),必须用全限定名区分。

掌握包和导入后,你的代码将更加结构化,团队协作和大型项目管理也会更轻松!遇到问题时,多动手写代码实践,理解会更深刻。


JavaSE核心知识点02面向对象编程02-05(方法)

作为 Java 初学者,理解**方法(Method)**是掌握编程的关键一步。方法是 Java 中封装代码逻辑的基本单元,类似于生活中的“工具”或“功能”。下面我会用通俗易懂的方式详细讲解,并附上代码示例。


一、方法是什么?

  • 定义:方法是一段有名字的代码块,用于完成特定任务(如计算、数据处理等)。
  • 类比:假设榨汁机是一个方法,你放入水果(输入参数),它榨汁(执行代码),返回果汁(返回值)。
  • 核心作用复用代码(避免重复写相同逻辑)、模块化(分解复杂问题)。

二、方法的组成

一个方法由以下部分组成(逐步拆解):

// 示例:计算两数之和的方法
public static int add(int a, int b) {  // 方法头(声明)int sum = a + b;                  // 方法体(具体逻辑)return sum;                       // 返回值
}
  1. 修饰符(如 public static):

    • public:方法可以被其他类访问。
    • static:静态方法,可通过类名直接调用(无需创建对象)。
  2. 返回类型(如 int):

    • 方法执行后返回的数据类型(如 int, String, void 表示无返回值)。
  3. 方法名(如 add):

    • 遵循驼峰命名法(如 calculateSum, printMessage)。
  4. 参数列表(如 (int a, int b)):

    • 输入的数据,可以是零个或多个参数,用逗号分隔。
  5. 方法体{} 中的代码):

    • 实现具体功能的代码逻辑。
  6. 返回值(如 return sum):

    • 必须与声明的返回类型匹配,若返回类型是 void,则无需 return

三、如何定义方法?

1. 无参数、无返回值的方法
public static void sayHello() {System.out.println("Hello, Java!");
}
2. 带参数、有返回值的方法
// 检查是否为偶数
public static boolean isEven(int number) {return number % 2 == 0;
}
3. 多个参数的方法
// 计算三个数的最大值
public static int max(int a, int b, int c) {int maxValue = a;if (b > maxValue) maxValue = b;if (c > maxValue) maxValue = c;return maxValue;
}

四、如何调用方法?

1. 调用静态方法(static修饰)
public class Main {public static void main(String[] args) {// 直接通过类名调用静态方法int result = add(3, 5); // 调用示例中的 add 方法System.out.println(result); // 输出 8}public static int add(int a, int b) {return a + b;}
}
2. 调用非静态方法(需要对象实例)
public class Calculator {// 非静态方法public int multiply(int a, int b) {return a * b;}public static void main(String[] args) {// 1. 创建对象Calculator calc = new Calculator();// 2. 通过对象调用方法int product = calc.multiply(4, 5);System.out.println(product); // 输出 20}
}

五、方法的重载(Overload)

  • 定义:同一个类中,方法名相同,但参数列表不同(类型、数量、顺序)。
  • 作用:提供多种处理方式,简化调用。
public class OverloadDemo {// 重载 add 方法public static int add(int a, int b) {return a + b;}public static double add(double a, double b) {return a + b;}public static int add(int a, int b, int c) {return a + b + c;}public static void main(String[] args) {System.out.println(add(2, 3));       // 调用 int 版本System.out.println(add(2.5, 3.5));   // 调用 double 版本System.out.println(add(1, 2, 3));    // 调用三个参数的版本}
}

六、递归方法(Recursion)

  • 定义:方法内部调用自身。
  • 关键:必须有一个终止条件,否则会无限递归导致栈溢出。
// 计算 n 的阶乘(n!)
public static int factorial(int n) {if (n == 0 || n == 1) {return 1; // 终止条件} else {return n * factorial(n - 1); // 递归调用}
}public static void main(String[] args) {System.out.println(factorial(5)); // 输出 120(5! = 5×4×3×2×1)
}

七、常见问题解答

1. 方法是否需要返回值?
  • 如果方法需要返回结果,用 return 指定返回类型(如 int, String)。
  • 如果只是执行操作(如打印),返回类型设为 void
2. 参数传递是“值传递”还是“引用传递”?
  • Java 是值传递:方法内修改基本类型参数的值不会影响原始变量;对象类型参数传递的是对象引用的副本(修改对象属性会影响原对象)。
3. 静态方法 vs 非静态方法?
  • 静态方法:属于类,通过 类名.方法名() 调用。
  • 非静态方法:属于对象,需先创建对象再调用。

八、总结与练习

  • 核心要点
    • 方法是封装代码的工具。
    • 通过参数接收输入,通过返回值输出结果。
    • 学会方法重载和递归。
  • 练习
    1. 写一个方法,判断一个数是否为素数。
    2. 写一个方法,反转字符串(如输入 “hello”,返回 “olleh”)。
    3. 用递归实现斐波那契数列。

通过以上内容,你应该对 Java 方法有了全面的理解。如果遇到问题,可以随时问我!


JavaSE核心知识点02面向对象编程02-06(泛型)

泛型(Generics)是 Java 中非常重要的特性,它让代码更安全、更灵活。下面用通俗易懂的方式为你讲解,包含代码示例和核心概念。


一、为什么需要泛型?

问题:假设你要写一个可以存放任何类型数据的容器(比如一个盒子)。没有泛型时,代码可能这样写:

class Box {private Object data;  // 用 Object 存储任意类型public void setData(Object data) {this.data = data;}public Object getData() {return data;}
}

缺陷

  • 取出数据时需要强制类型转换,容易出错。
  • 无法限制放入的类型,可能混入不同类型的数据。

泛型的解决方案:让容器在定义时声明它能存储的数据类型。

Box<String> box = new Box<>();  // 只能存 String
box.setData("Hello");           // 正确
// box.setData(123);            // 编译报错!
String data = box.getData();    // 无需强制转换

二、泛型的基本语法

1. 定义泛型类/接口

在类名后加<T>T是类型参数(可以是任意标识符,如E, K, V等)。

class Box<T> {  // T 表示“某种类型”private T data;public void setData(T data) {this.data = data;}public T getData() {return data;}
}
2. 使用泛型类

创建对象时指定具体类型:

Box<String> stringBox = new Box<>();  // 存储 String
Box<Integer> intBox = new Box<>();    // 存储 Integer

三、泛型方法

即使类不是泛型,方法也可以独立声明泛型:

public class Utils {// 泛型方法:在返回类型前加 <T>public static <T> void printArray(T[] array) {for (T element : array) {System.out.println(element);}}
}// 使用
Integer[] intArray = {1, 2, 3};
Utils.printArray(intArray);  // 自动推断类型为 Integer

四、泛型通配符 ?

用于处理未知类型,常见于方法参数或集合操作。

1. 无界通配符 <?>

表示接受任何类型:

public static void printList(List<?> list) {for (Object elem : list) {System.out.println(elem);}
}
2. 上界通配符 <? extends T>

表示类型是T或其子类:

// 只能读取元素(因为元素是 Animal 或其子类)
public static void processAnimals(List<? extends Animal> animals) {for (Animal animal : animals) {animal.eat();}
}
3. 下界通配符 <? super T>

表示类型是T或其父类:

// 可以写入元素(因为容器是 T 的父类)
public static void addNumbers(List<? super Integer> list) {list.add(123);  // 允许添加 Integer
}
PECS 原则(Producer Extends, Consumer Super)
  • 生产者(Producer):使用<? extends T>,只能读取。
  • 消费者(Consumer):使用<? super T>,只能写入。

五、类型擦除(Type Erasure)

Java 泛型在编译后会被擦除为原始类型(如Object),这是为了兼容旧版本 Java。例如:

List<String> list = new ArrayList<>();
// 编译后实际是:List list = new ArrayList();

影响

  • 运行时无法获取泛型的具体类型(如T的实际类型)。
  • 不能创建泛型数组(如new T[])。
  • 泛型类型不能是基本类型(如List<int>错误,要用List<Integer>)。

六、泛型的限制与注意事项

  1. 不能实例化类型参数

    // 错误!new T() 是非法的
    T data = new T();
    
  2. 静态成员不能使用泛型类型

    class Box<T> {// 错误!静态变量不能是泛型private static T staticData;
    }
    
  3. 泛型与继承的关系

    • List<String> 不是 List<Object> 的子类。
    • ArrayList<String>List<String> 的子类。

七、典型应用场景

  1. 集合框架(如ArrayList<E>HashMap<K,V>)。
  2. 工具类(如Collections中的泛型方法)。
  3. 自定义通用数据结构(如栈、队列、链表)。

八、代码示例:自定义泛型栈

class Stack<T> {private List<T> elements = new ArrayList<>();public void push(T element) {elements.add(element);}public T pop() {if (elements.isEmpty()) {throw new EmptyStackException();}return elements.remove(elements.size() - 1);}
}// 使用
Stack<Integer> stack = new Stack<>();
stack.push(1);
int num = stack.pop();  // 无需强制转换

九、总结

  • 核心目的:提高代码的类型安全性和复用性。
  • 关键语法<T>定义泛型,?处理未知类型。
  • 注意事项:类型擦除、通配符的使用场景、PECS原则。

掌握泛型后,你将能写出更健壮、更灵活的 Java 代码!


JavaSE核心知识点02面向对象编程02-07(枚举)

以下是关于Java泛型的详细讲解,从基础概念到实际应用逐步展开:


一、泛型存在的意义

1.1 类型安全

// 泛型出现前的集合使用(JDK1.5之前)
List list = new ArrayList();
list.add("Hello");
list.add(100); // 编译通过,运行时可能抛出ClassCastExceptionString str = (String) list.get(1); // 运行时报错:Integer无法转String

1.2 代码复用
通过泛型实现通用容器:

// 泛型类定义
public class Box<T> {private T content;public void set(T content) { this.content = content; }public T get() { return content; }
}// 使用时指定具体类型
Box<String> stringBox = new Box<>();
Box<Integer> intBox = new Box<>();

二、泛型核心语法

2.1 泛型类

// 多类型参数示例
public class Pair<K, V> {private K key;private V value;public Pair(K key, V value) {this.key = key;this.value = value;}public K getKey() { return key; }public V getValue() { return value; }
}// 使用示例
Pair<String, Integer> pair = new Pair<>("age", 25);

2.2 泛型方法

// 独立于类的泛型方法
public class Utils {public static <T> void printArray(T[] array) {for (T element : array) {System.out.print(element + " ");}System.out.println();}
}// 调用示例
Integer[] intArr = {1, 2, 3};
Utils.<Integer>printArray(intArr); // 显式指定类型
Utils.printArray(new String[]{"A", "B"}); // 自动类型推断

2.3 泛型接口

// 泛型接口定义
public interface Generator<T> {T generate();
}// 实现类指定具体类型
class StringGenerator implements Generator<String> {@Overridepublic String generate() {return UUID.randomUUID().toString();}
}

三、类型通配符

3.1 上界通配符(<? extends T>)

// 接收Number及其子类集合
public static double sum(List<? extends Number> list) {double sum = 0;for (Number num : list) {sum += num.doubleValue();}return sum;
}// 可以传入List<Integer>或List<Double>
List<Integer> ints = Arrays.asList(1,2,3);
System.out.println(sum(ints)); // 输出6.0

3.2 下界通配符(<? super T>)

// 向集合中添加元素
public static void addNumbers(List<? super Integer> list) {for (int i = 1; i <= 5; i++) {list.add(i);}
}List<Number> numbers = new ArrayList<>();
addNumbers(numbers); // 合法操作

3.3 无界通配符(<?>)

// 仅需遍历集合元素时不关心类型
public static void printList(List<?> list) {for (Object elem : list) {System.out.print(elem + " ");}System.out.println();
}

四、类型擦除与限制

4.1 类型擦除原理
编译后泛型类型会被擦除为原始类型:

// 编译前
List<String> list = new ArrayList<>();// 编译后(字节码层面)
List list = new ArrayList();

4.2 泛型限制

  • 无法实例化类型参数
public class Box<T> {// 错误写法private T instance = new T(); // 正确方式通过反射(需谨慎)public T createInstance(Class<T> clazz) throws Exception {return clazz.newInstance();}
}
  • 无法使用基本类型
// List<int> list; // 编译错误
List<Integer> list; // 正确
  • 静态成员不能使用类型参数
public class Box<T> {// static T staticField; // 错误
}

五、泛型高级应用

5.1 泛型与反射

public class GenericFactory<T> {private Class<T> type;public GenericFactory(Class<T> type) {this.type = type;}public T createInstance() throws Exception {return type.getDeclaredConstructor().newInstance();}
}// 使用示例
GenericFactory<StringBuilder> factory = new GenericFactory<>(StringBuilder.class);
StringBuilder sb = factory.createInstance();

5.2 泛型数组

// 正确创建泛型数组的方式
public class ArrayMaker<T> {private Class<T> kind;public ArrayMaker(Class<T> kind) {this.kind = kind;}@SuppressWarnings("unchecked")T[] create(int size) {return (T[]) Array.newInstance(kind, size);}
}// 使用示例
ArrayMaker<String> maker = new ArrayMaker<>(String.class);
String[] strArray = maker.create(10);

六、最佳实践与常见错误

6.1 PECS原则(Producer Extends, Consumer Super)

// 正确使用示例
public static <T> void copy(List<? super T> dest, List<? extends T> src) {for (T item : src) {dest.add(item);}
}List<Number> dest = new ArrayList<>();
List<Integer> src = Arrays.asList(1,2,3);
copy(dest, src); // 正确执行

6.2 常见错误示例

// 错误1:类型不匹配
List<String> list = new ArrayList<Object>(); // 编译错误// 错误2:原始类型警告
List rawList = new ArrayList<String>(); // 编译警告
rawList.add(100); // 运行时可能出错

七、学习建议

  1. 实践路线

    • 从集合框架(如ArrayList)开始体验泛型
    • 尝试自定义泛型类(如实现一个通用缓存类)
    • 研究JDK源码中的泛型应用(如Comparable接口)
  2. 调试技巧

    • 使用javac -Xlint:unchecked查看未检查警告
    • 在IDE中观察类型擦除后的字节码
  3. 延伸学习

    • 泛型与设计模式(如工厂模式、策略模式)
    • Java8后的改进(如泛型类型推断增强)
    • Kotlin/Scala等JVM语言的泛型特性对比

通过系统学习和大量编码实践,通常可在2-3周内掌握泛型的核心用法。理解难点时,建议通过绘制类型关系图辅助记忆(如通配符的继承关系)。


JavaSE核心知识点02面向对象编程02-8(异常处理)

好的!作为Java新手,掌握异常处理是编写健壮程序的关键。以下是一份详细的Java异常处理指南,包含基础概念、使用方法和实际示例:


一、异常处理的核心概念

1. 什么是异常?
  • 异常(Exception):程序运行时发生的非正常情况,会中断正常的指令流。
  • 异常处理的必要性:避免程序崩溃、提供友好错误提示、确保资源正确释放。
2. Java异常分类

Java异常体系以 Throwable 为根类,分为两类:

  • Error:严重错误(如内存溢出 OutOfMemoryError),程序无法处理。
  • Exception:可处理的异常,分为两类:
    • Checked Exception(检查型异常):编译时强制检查(如 IOException)。
    • Unchecked Exception(非检查型异常):运行时异常(如 NullPointerExceptionArithmeticException)。

二、异常处理的关键字

1. try-catch-finally
try {// 可能抛出异常的代码int result = 10 / 0; // 抛出 ArithmeticException
} catch (ArithmeticException e) {// 捕获并处理异常System.out.println("除数不能为零!");
} finally {// 无论是否发生异常,都会执行的代码(常用于释放资源)System.out.println("执行finally块");
}
2. throws

声明方法可能抛出的异常,由调用者处理:

public void readFile() throws IOException {FileReader file = new FileReader("test.txt");// ...
}
3. throw

手动抛出异常对象:

if (age < 0) {throw new IllegalArgumentException("年龄不能为负数!");
}

三、常见异常类型与处理

1. 常见异常示例
异常类型触发场景处理建议
NullPointerException调用 null 对象的方法或属性检查对象是否为 null
ArrayIndexOutOfBounds访问数组越界位置检查数组索引范围
IOException文件读写失败(如文件不存在)使用 try-catchthrows
NumberFormatException字符串转换为数字失败(如 "abc"校验输入是否为有效数字
2. 处理多个异常
try {FileInputStream fis = new FileInputStream("file.txt");int data = fis.read();
} catch (FileNotFoundException e) {System.out.println("文件未找到!");
} catch (IOException e) {System.out.println("读取文件失败!");
} catch (Exception e) {// 兜底处理(不建议滥用)System.out.println("未知错误!");
}

四、自定义异常

1. 创建自定义异常类
public class InsufficientBalanceException extends Exception {public InsufficientBalanceException(String message) {super(message);}
}
2. 使用自定义异常
public void withdraw(double amount) throws InsufficientBalanceException {if (amount > balance) {throw new InsufficientBalanceException("余额不足!");}balance -= amount;
}

五、最佳实践与常见陷阱

1. 最佳实践
  • 精准捕获:避免捕获过于宽泛的异常(如直接 catch (Exception e))。
  • 资源释放:使用 try-with-resources(Java 7+)自动关闭资源:
    try (FileInputStream fis = new FileInputStream("file.txt")) {// 使用资源
    } catch (IOException e) {e.printStackTrace();
    }
    
  • 记录异常:使用日志工具(如 log4j)记录异常堆栈:
    catch (SQLException e) {logger.error("数据库操作失败", e);
    }
    
2. 常见陷阱
  • 忽略异常:空 catch 块会隐藏问题。
    // 错误示例!
    try {// 可能出错的代码
    } catch (Exception e) {// 空处理
    }
    
  • 在finally中return:可能导致异常被覆盖。
    try {// ...
    } finally {return; // 不推荐!
    }
    

六、总结与练习

1. 关键点总结
  • 分类:理解Checked vs Unchecked异常的区别。
  • 处理方式try-catchthrowsthrow的适用场景。
  • 资源管理:优先使用 try-with-resources 替代手动关闭。
2. 练习题目
  1. 编写代码读取文件内容,处理可能的 FileNotFoundException
  2. 实现一个除法方法,当除数为零时抛出 ArithmeticException
  3. 自定义一个 InvalidEmailException,并在用户输入无效邮箱时抛出。

通过实际编码练习,逐步掌握异常处理的核心技巧!遇到问题时,可查阅 Java官方文档 或调试工具(如IDE的断点功能)。



📜文末寄语

  • 🟠关注我,获取更多内容。
  • 🟡技术动态、实战教程、问题解决方案等内容持续更新中。
  • 🟢《全栈知识库》技术交流和分享社区,集结全栈各领域开发者,期待你的加入。
  • 🔵​加入开发者的《专属社群》,分享交流,技术之路不再孤独,一起变强。
  • 🟣点击下方名片获取更多内容🍭🍭🍭👇

相关文章:

  • deep-rtsp 摄像头rtsp配置工具
  • 多线程(八)
  • 高等数学-常微分方程
  • 5.22 打卡
  • 我的世界模组开发——水平方向的方块(3)
  • java面试每日一背 day2
  • Python绘制3D图表
  • 数据指标体系:企业数字化转型的“数字基因“革命
  • 前端判空:与后端 “千层套路” 的斗智斗勇
  • mysql 创建用户,创建数据库,授权
  • 企业级调度器LVS TUN实践
  • 今日行情明日机会——20250522
  • Java的常见算法和Lambda表达式
  • NMEA定位测试,硬件验证
  • 监控易一体化运维:网络拓扑管理,网络管理高效之道
  • 无人机影像水面拼接、海面拼接
  • Matlab学习合集
  • halcon轮廓处理(不同线段用不同颜色显示)与交点检测
  • Python的文本操作和try语句使用
  • day1 大模型学习 Qwen系列学习
  • 网站建设与管理题库/关键词林俊杰无损下载
  • 怎么做网站里面的模块/今天发生的重大新闻5条
  • 阜宁住房和城乡建设局网站/bing搜索引擎国内版
  • win2003 wordpress/淘宝标题优化网站
  • 阿里云做企业网站/聊城优化seo
  • 专做洗衣柜的网站/怎么申请网址