学习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. 局部代码块

    • 临时限制变量作用域(较少使用)
相关推荐
Coder_Boy_2 小时前
基于SpringAI的在线考试系统-DDD(领域驱动设计)核心概念及落地架构全总结
java·大数据·人工智能·spring boot·架构·ddd·tdd
Two_brushes.2 小时前
C++ 常见特殊类的设计(含有单例模式)
开发语言·c++
不会c嘎嘎2 小时前
QT -- 窗口
开发语言·qt
LawrenceLan2 小时前
Flutter 零基础入门(二十一):Container、Padding、Margin 与装饰
开发语言·前端·flutter·dart
lsx2024062 小时前
C++ 注释
开发语言
黎雁·泠崖2 小时前
Java初识面向对象+类与对象+封装核心
java·开发语言
齐鲁大虾2 小时前
如何通过C#调取打印机打印文本和图片
开发语言·c#
悟能不能悟2 小时前
java controller的DTO如果有内部类,应该注意什么
java·开发语言
没有才华的Mr.L2 小时前
【JavaSE】数组
java·开发语言