学习Java40天

权限修饰符 (Access Modifiers)

权限修饰符用于控制类、成员变量、方法、构造方法和内部类的可访问范围。

一、权限修饰符的分类与作用范围

Java 提供了四种访问权限,范围从严格到宽松:

修饰符 同一个类中 同一个包中其他类 不同包子类 不同包无关类
private ✅ ❌ ❌ ❌
默认 (default) (不写任何修饰符) ✅ ✅ ❌ ❌
protected ✅ ✅ ✅ ❌
public ✅ ✅ ✅ ✅

访问范围总结:

  • private:仅本类可访问。

  • 默认:本类 + 同包其他类。

  • protected:本类 + 同包其他类 + 不同包的子类。

  • public:所有位置都可访问。

二、权限修饰符的使用规则(最佳实践)

  1. 成员变量通常私有化:

    java

    复制代码
    public class Student {
        private String name;  // 成员变量私有
        private int age;
    }
    • 原因:保护数据,防止外部直接修改,通过公有方法进行控制。
  2. 方法通常公开:

    java

    复制代码
    public class Student {
        private String name;
        
        // 公开的getter/setter方法
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        
        // 公开的业务方法
        public void study() {
            System.out.println(name + "正在学习");
        }
    }
  3. 特殊情况:

    • 私有方法 :如果某个方法只是为类内部其他方法提供辅助功能(抽取的共性代码),应该设置为 private。

    java

    复制代码
    public class Calculator {
        public int add(int a, int b) {
            validateInput(a, b);
            return a + b;
        }
        
        public int multiply(int a, int b) {
            validateInput(a, b);
            return a * b;
        }
        
        // 私有方法:内部辅助方法,不需要对外公开
        private void validateInput(int a, int b) {
            if (a < 0 || b < 0) {
                throw new IllegalArgumentException("参数不能为负数");
            }
        }
    }

代码块 (Code Blocks)

代码块是使用 {} 括起来的代码段,根据定义位置和关键字的不同,分为以下几种:

一、局部代码块

  • 位置:方法内部

  • 作用:限定变量生命周期,及早释放内存(现代JVM优化已使其作用不明显)

  • 特点:执行时机与普通语句相同

java

复制代码
public void demo() {
    // 普通代码
    int x = 10;
    System.out.println(x);
    
    // 局部代码块
    {
        int y = 20;  // y的作用域仅限于此代码块内
        System.out.println(y);
    }
    
    // System.out.println(y); // 编译错误!y已超出作用域
    System.out.println(x);   // x仍然有效
}

二、构造代码块(实例代码块)

  • 位置:类中方法外,成员位置

  • 格式 :直接使用 {}

  • 特点:

    1. 每次创建对象时都会执行

    2. 先于构造方法执行

    3. 用于提取多个构造方法的公共代码

java

复制代码
public class Person {
    private String name;
    
    // 构造代码块
    {
        System.out.println("构造代码块执行:初始化公共部分");
        // 这里可以放所有构造方法都需要执行的代码
    }
    
    // 无参构造
    public Person() {
        System.out.println("无参构造执行");
    }
    
    // 有参构造
    public Person(String name) {
        this.name = name;
        System.out.println("有参构造执行");
    }
}

// 测试
public class Test {
    public static void main(String[] args) {
        Person p1 = new Person();
        // 输出:
        // 构造代码块执行:初始化公共部分
        // 无参构造执行
        
        Person p2 = new Person("张三");
        // 输出:
        // 构造代码块执行:初始化公共部分
        // 有参构造执行
    }
}

三、静态代码块

  • 位置:类中方法外,成员位置

  • 格式 :static {}

  • 特点:

    1. 随着类的加载而执行(只执行一次)

    2. 先于构造代码块和构造方法执行

    3. 用于初始化静态变量或执行只需一次的初始化操作

java

复制代码
public class DatabaseUtil {
    // 静态变量
    private static String driver;
    private static String url;
    
    // 静态代码块:类加载时执行,只执行一次
    static {
        System.out.println("静态代码块执行:加载数据库配置");
        driver = "com.mysql.jdbc.Driver";
        url = "jdbc:mysql://localhost:3306/test";
        // 这里可以进行复杂的初始化,如读取配置文件
    }
    
    // 构造代码块
    {
        System.out.println("构造代码块执行");
    }
    
    public DatabaseUtil() {
        System.out.println("构造方法执行");
    }
    
    public static void connect() {
        System.out.println("使用配置连接数据库...");
    }
}

// 测试
public class Test {
    public static void main(String[] args) {
        // 第一次使用类,触发静态代码块
        DatabaseUtil.connect();
        // 输出:
        // 静态代码块执行:加载数据库配置
        // 使用配置连接数据库...
        
        // 创建对象,触发构造代码块和构造方法
        DatabaseUtil util1 = new DatabaseUtil();
        // 输出:
        // 构造代码块执行
        // 构造方法执行
        
        // 再次创建对象,静态代码块不会再次执行
        DatabaseUtil util2 = new DatabaseUtil();
        // 输出:
        // 构造代码块执行
        // 构造方法执行
    }
}

四、代码块执行顺序总结

java

复制代码
public class Example {
    // 静态变量
    private static String staticField = "静态变量";
    
    // 静态代码块
    static {
        System.out.println("1. 静态代码块执行");
    }
    
    // 实例变量
    private String instanceField = "实例变量";
    
    // 构造代码块
    {
        System.out.println("3. 构造代码块执行");
    }
    
    // 构造方法
    public Example() {
        System.out.println("4. 构造方法执行");
    }
}

// 测试
public class Test {
    static {
        System.out.println("Test类的静态代码块");
    }
    
    public static void main(String[] args) {
        System.out.println("开始创建对象...");
        Example e = new Example();
        // 输出顺序:
        // Test类的静态代码块(先加载Test类)
        // 开始创建对象...
        // 1. 静态代码块执行(加载Example类)
        // 3. 构造代码块执行
        // 4. 构造方法执行
        
        // 注意:静态变量和实例变量的初始化在实际执行中可能更早
    }
}

执行顺序原则:

  1. 父类静态代码块 → 子类静态代码块(继承时)

  2. 父类构造代码块 → 父类构造方法

  3. 子类构造代码块 → 子类构造方法

五、实际应用场景

  1. 静态代码块:

    • 加载数据库驱动:Class.forName("com.mysql.jdbc.Driver");

    • 读取配置文件

    • 初始化静态工具

  2. 构造代码块:

    • 多个构造方法的公共初始化逻辑

    • 对象创建前的统一检查或设置

  3. 局部代码块:

    • 临时限制变量作用域(较少使用)
相关推荐
m0_587383002 小时前
广州 24 小时自助健身房解决方案技术实现与实战指南
java·spring·小程序·架构·需求分析
·云扬·2 小时前
Prompt 工程与安全:从 System 设计到注入防御
java·人工智能·安全·ai·prompt
专注仿真2 小时前
引擎扩展性与集成设计深度剖析:从 14 个扩展点到 DIS→HLA 演进之路
开发语言·算法·仿真引擎·推演引擎
Best-Wishes3 小时前
科来网络分析系统(技术交流版)使用说明书
开发语言·junit·php
代码不停3 小时前
自动化测试(java)
java·开发语言·selenium·自动化
滕州市燕猫虎计算机科技工作室个体工商户4 小时前
《Rust程序设计》学习笔记八:结构体
笔记·学习·rust·rust程序设计
别动我齐刘海4 小时前
Linux 系统调试学习1
linux·运维·服务器·c++·学习·机器学习·机器人
鬼手点金5 小时前
opencode-rules 插件
java·开发语言·前端·人工智能·chrome·git·github
爱上网的小舟5 小时前
星际战士2启动错误怎么办?5种游戏报错解决方法
开发语言·php
xier_ran6 小时前
【infra之路】AI 编译器学习笔记(二):重拾 C++——移动语义与 LLVM 风格的类型转换
人工智能·笔记·学习