java中对于static与非static的最通俗的讲解!!!关于静态代码块的解释可以更加了解static机制)

本文详细解析了static与非static变量的区别,包括作用范围、存放位置及创建时间的不同。通过代码示例说明static变量在类初始化时即被创建,而全局存在;非static变量则依赖于对象实例化。

static与非static的不同之处:

1:作用范围:访问权限不同
static变量是全局的,是类的所有对象都能访问的,是所有方法都可以访问的。
而非static变量是私有的,是有访问限制的,就是说是每个对象独有的特有的,并且只有非static方法才可以访问。
2:创建时的存放位置不同
学过C++的胖友应该会了解 static是全局变量 他在类初始化时就会被初始化,而非static变量不会。
3:创建的时间不同 static会提前创建
在这里插入图片描述
下面的代码便可证明:
在这里插入图片描述
你会发现不是静态的函数不可以被直接调用,但是静态的函数可以被直接调用,那是因为,在创立类的时候,static已经被创建,而此时的非static函数是没有被创建的,也表明了static函数可以不通过类的实例化便可以调用,但是非静态函数必须通过实例化对象调用,这也与他们的创建时间与范围有关static类型的变量会在类被创建时自动被创建!
在这里插入图片描述

public class Student {
    {
        System.out.println("代码块");
    }
    
    static{
        System.out.println("静态代码块");
    }
    Student()
    {
        System.out.println("类的默认构造函数");
    }

    public static void main(String[] args) {
        Student student = new Student();


    }
}

运行结果如下:
在这里插入图片描述

你会发现static永远是第一个被创造的,
并且只创建一次之后就会全局存在!

<think>好的,我现在需要解释Java中的static块的作用。首先,用户可能已经知道static变量,但想了解static块的相关知识。我需要先回顾static变量的初始化,然后引入static块的概念。 用户之前问过static变量和临时变量的初始化区别,现在问static块,可能是在实际编码中遇到了需要复杂初始化static变量的情况。用户可能想知道static块的作用、执行时机、以及使用场景。 首先,我应该明确static块的基本定义,它是在类加载时执行的一次性初始化块。然后,需要说明它的执行时机,即在类被首次加载时,且在static变量显式赋值之后。这可能和之前提到的static变量初始化阶段有关联,需要联系起来。 接下来,需要举例说明static块的用法,比如初始化静态变量,特别是当初始化逻辑比较复杂,无法用单行表达式完成时。比如读取配置文件、建立数据库连接等。同时,要注意到static块只能访问静态成员,不能访问实例变量,这一点需要强调,避免用户误用。 另外,可能需要提到多个static块的执行顺序,按照它们在代码中的顺序执行。这也是一个容易忽略的点,特别是当类中有多个static块时,用户需要知道它们的执行顺序。 用户可能还会好奇static块和构造代码块的区别,这时候可以简要对比一下。static块用于类初始化,构造代码块用于实例初始化,每次创建对象时执行。 同时,要注意可能的常见错误,比如在static块中访问实例变量或方法,这会导致编译错误。需要提醒用户只能在static块中处理静态成员。 后,总结static块的适用场景,强调它在复杂静态初始化中的作用,帮助用户理解何时使用static块而不是直接在声明时赋值。 需要确保语言通俗易懂,避免过于技术化的术语,但又要准确。可以结合代码示例,让用户更直观地理解。同时,检查之前对话中提到的static变量初始化流程,确保信息一致,帮助用户建立完整的知识体系。</think>--- ### **核心概念** `static{}` 块(静态初始化块)是 Java 中用于**类级别初始化**的代码块。它在类加载到内存时**自动执行一次**,且**仅执行一次**,主要用于初始化静态变量(`static` 修饰的变量)或执行类加载时需要的一次性操作(如加载配置文件、连接数据库等)。 --- ### **核心特性** 1. **执行时机**: - 在类被**首次主动使用**(如创建实例、访问静态方法/变量等)时触发类加载。 - 在类加载的**初始化阶段**(即类加载的后一步)执行,**晚于静态变量的默认赋值,早于实例对象的创建**。 2. **执行顺序**: - 如果有多个 `static{}` 块,按代码中的**书写顺序依次执行**。 - `static{}` 的执行**优先于**静态变量的显式赋值。 ```java public class Example { static int x = 10; // 静态变量显式赋值 static { x = 20; } // static块修改x的值 static { System.out.println(x); } // 输出20(注意顺序!) } ``` 3. **作用范围**: - 只能操作**静态成员**(静态变量、静态方法),不能访问实例变量或方法(因为此时对象尚未创建)。 --- ### **常见使用场景** 1. **初始化复杂静态变量**: 当静态变量的初始化需要多步逻辑(如读取文件、计算值)时,用 `static{}` 块封装代码。 ```java public class Config { static Map<String, String> configMap; static { configMap = new HashMap<>(); // 从文件加载配置到configMap try (BufferedReader reader = new BufferedReader(new FileReader("config.txt"))) { String line; while ((line = reader.readLine()) != null) { String[] parts = line.split("="); configMap.put(parts[0], parts[1]); } } catch (IOException e) { e.printStackTrace(); } } } ``` 2. **注册驱动或连接池**: 例如 JDBC 驱动注册(如 `Class.forName("com.mysql.jdbc.Driver")`)。 ```java public class Database { static Connection connection; static { try { connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "user", "pass"); } catch (SQLException e) { e.printStackTrace(); } } } ``` 3. **全局资源预加载**: 如缓存预热、日志系统初始化等。 --- ### **与构造代码块的区别** | **特性** | `static{}` 块 | 构造代码块 `{}` | |------------------|-----------------------------------|----------------------------------| | **执行时机** | 类加载时执行一次 | 每次创建对象时执行(在构造函数前) | | **作用对象** | 类级别(静态成员) | 实例级别(初始化实例变量) | | **内存位置** | 方法区(类元数据) | 堆内存(对象内部) | | **典型用途** | 全局配置、静态资源初始化 | 对象共性的初始化逻辑 | --- ### **底层原理** 1. **类加载过程**: - **加载** → **验证** → **准备** → **解析** → **初始化** → 使用 → 卸载。 - `static{}` 块在**初始化阶段**执行,JVM 会生成一个 `<clinit>` 方法(类初始化方法)来合并所有静态变量赋值和 `static{}` 块中的代码。 2. **字节码验证**: 通过 `javap -c Example.class` 查看字节码,可以看到 `<clinit>` 方法: ```java public class Example { static int x; static { x = 20; } } ``` 对应的字节码: ```bash static {}; Code: 0: bipush 20 2: putstatic #2 // Field x:I 5: return ``` --- ### **注意事项** 1. **避免死循环**: 在 `static{}` 中直接或间接触发当前类的加载(如 `new Example()`),会导致类初始化死循环。 2. **异常处理**: `static{}` 块中若抛出未捕获的异常,JVM 会抛出 `ExceptionInInitializerError`,导致类初始化失败。 3. **性能影响**: 复杂的 `static{}` 逻辑会拖慢类加载速度,影响程序启动性能。 --- ### **总结** - **何时用**:需要一次性初始化静态变量或执行类加载时的全局操作。 - **怎么用**:将复杂初始化逻辑封装到 `static{}` 中,确保代码简洁且安全。 - **慎用场景**:避免在 `static{}` 中执行耗时操作或可能抛出未处理异常的逻辑。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值