Java中的static详细总结学习,一篇就够了

本文详细解释了Java中static关键字的作用,它用于区分类和对象的成员。static修饰的成员属于类,无需对象即可通过类名调用,而未被static修饰的成员属于对象。文章还探讨了类加载的顺序,包括静态代码块、构造器的执行顺序,并通过示例代码展示了类和子类加载、对象初始化的过程。
部署运行你感兴趣的模型镜像

用途:static关键字是用来区分类和对象的。

被static修饰的属于类,叫做(类成员、静态成员、类变量),可以直接通过(类.成员)来调用

不被static修饰的属于对象,叫做(对象成员、非静态成员、实例变量)可以通过(对象.成员)来调用。

static代码块可以出现在类的任何地方,绝对不能出现在方法中。

被static修饰的不用通过对象来访问,直接通过类来访问。

静态域 分为静态变量,静态方法,静态块。 当执行到静态域时,按着静态域的顺序加载,并且静态域只在类的第一次加载时被执行。

被static修饰的代码中,不能出现this和super这两个关键字。this表示这个类的当前实例,super表示父类的当前实例;static属于类,this是类的对象,当然不能调用。

被static修饰的静态代码块的作用,提升程序性能。

被static修饰的代码,在类加载的时候加载。

在静态方法中不能访问非静态成员变量和非静态成员方法,但在非静态成员方法中可以访问静态变量和静态方法。

学习下面代码的输出顺序:

public class Test {
    People p=new People("WanYuan");
    static{
        System.out.println("test static");
    }
    public Test(){
        System.out.println("Test的无参构造方法");
    }

    public static void main(String[] args) {
        new MyClass();
    }

}
class People{
    static {
        System.out.println("people static");
    }

    public People(String str){
        System.out.println("people"+str);
    }
}
class MyClass extends My{
    People p=new People("JiaLuo");
    static{
        System.out.println("MyClass static");
    }
    public MyClass() {
        System.out.println("MyClass constructor");
    }

}
class My{
    static{
        System.out.println("My static");
    }
}

输出结果为:

 1.先找到main方法,main方法是程序的入口,执行main方法之前,先加载main方法所在的类Test。

2.加载Test类时,发现有static修饰的代码块,所以先打印 test static。

3.Test加载完成后,执行main方法中的 new MyClass(),执行代码之前先加载new MyClass()所在的类MyClass,但是MyClass继承父类My,所以先加载父类My再加载MyClass类。

4.加载My时有静态代码块输出My static ,加载MyClass时有静态代码块输出MyClass static。

5. 加载完类之后,调用MyClass的构造器生成对象(new MyClass( )  ),生成对象之前,需要先初始化父类的成员变量,如果父类中有People p=new People("people"),并加载People类。本例中并没有,所以初始化父类,没有变化。

6.这个例子中,父类中没有People p=new People("people")。调用MyClass的构造器生成对象(new MyClass( )  )之前,接下来需要调用父类的无参构造函数,本例中父类也没有无参构造函数。

7.解决完父类的初始化对象和调用无参构造函数之后,调用MyClass的构造器生成对象(new MyClass( )  ),发现MyClass还没有初始化,所以接着初始化MyClass类。初始化MyClass时发现还有People类没有加载,所以先加载People类。

8.加载People类,发现有static代码块,先执行static代码块,输出people static。

9.接着完成people类的初始化执行People的构造器,输出peopleJiaLuo。

10.最后调用Myclass类的构造器,完成MyClass类的初始化。

总结:先加载类再初始化类;

在没有继承父类的情况下,Class类加载的先后顺序如下:

在继承父类的情况下,Class类的加载顺序如下:

父类静态----->子类静态----->父类非静态----->父类构造函数----->子类非静态----->子类构造函数

 静态代码块,构造代码块,无参构造函数,有参构造函数,普通代码块执行顺序

public class Test03 {
    static{
        System.out.println("这是静态代码块");
    }

    {
        System.out.println("这是构造代码块");
    }

    public Test03(){
        System.out.println("这是无参构造");
    }

    public Test03(String name){
        System.out.println("这是有参构造函数");
    }

    public void add(){
        System.out.println("这是普通代码块");
    }

    public static void main(String[] args) {
        Test03 test03=new Test03();
        Test03 test04=new Test03("JiaLuo");
    }
}

 程序先执行静态代码块,每次新建一个对象都会去执行构造代码块,代码中新建了两个对象,所以出现了两次构造代码块,构造代码块优先于构造函数执行,又依赖于构造函数。没有构造函数新建对象,就不会由构造代码块执行。

静态代码块(static{})在类加载的时候执行,是最早被执行的。
构造代码块({}内的部分)在每一次创建对象的时候执行,始终在构造方法前执行。
构造方法在新建对象的时候调用。
 

您可能感兴趣的与本文相关的镜像

ComfyUI

ComfyUI

AI应用
ComfyUI

ComfyUI是一款易于上手的工作流设计工具,具有以下特点:基于工作流节点设计,可视化工作流搭建,快速切换工作流,对显存占用小,速度快,支持多种插件,如ADetailer、Controlnet和AnimateDIFF等

Java 8 到 Java 17 的版本中引入了大量新特性,极大地提升了 Java 的表达能力、性能以及开发效率。以下是这些版本中主要新特性的总结,适用于学习和技术笔记。 ### 一、Java 8 新特性 Java 8 是一次重大更新,引入了许多现代编程语言的特性,主要包括: - **Lambda 表达式**:允许将函数作为参数传递,简化了集合操作和并发编程。 - **函数式接口**:仅包含一个抽象方法的接口,支持 Lambda 表达式作为函数式编程的基础。 - **方法引用**:通过 `ClassName::methodName` 或 `object::methodName` 的形式直接引用已有方法。 - **默认方法**:接口中可以包含默认实现的方法,使用 `default` 关键字修饰,解决了接口演进问题。 - **静态方法**:接口中也可以定义静态方法,便于工具方法的封装。 - **Stream API**:提供声明式的集合操作方式,支持链式调用,如 `filter`、`map`、`reduce` 等。 - **Optional 类**:用于避免空指针异常,鼓励更安全的代码风格。 - **新的日期时间 API(java.time)**:引入 `LocalDate`、`LocalTime`、`LocalDateTime` 等类,替代旧版 `Date` 和 `Calendar`,具有更好的线程安全性和易用性 [^3]。 ```java // 示例:Stream API 与 Lambda 表达式 List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David"); List<String> filtered = names.stream() .filter(name -> name.startsWith("A")) .map(String::toUpperCase) .toList(); ``` ### 二、Java 9 新特性 Java 9 引入了模块化系统,并增强了工具链和 API: - **模块系统(JPMS)**:通过 `module-info.java` 定义模块,提升大型系统的可维护性和安全性。 - **JShell(REPL)**:提供交互式命令行,方便快速测试 Java 代码片段。 - **接口私有方法**:允许接口中定义 `private` 方法,用于辅助默认方法实现。 - **HTTP/2 客户端(实验性)**:引入新的 HTTP 客户端 API,支持同步和异步请求 [^6]。 ### 三、Java 10 新特性 Java 10 增加了一些实用特性,提升开发效率: - **局部变量类型推断(var)**:允许使用 `var` 声明局部变量,编译器自动推断类型。 - **GC 改进**:引入并行 Full GC 的 G1 垃圾收集器。 - **统一垃圾回收接口**:为不同垃圾收集器提供统一接口,便于扩展 [^7]。 ```java // 示例:var 类型推断 var list = new ArrayList<String>(); list.add("Hello"); ``` ### 四、Java 11 新特性 Java 11 是一个长期支持版本(LTS),引入了多个增强功能: - **单文件源码执行(jshell-like)**:支持直接运行 `.java` 文件,无需显式编译。 - **HTTP Client API 增强**:支持同步和异步请求,支持 WebSocket。 - **字符串增强方法**:如 `isBlank()`, `lines()`, `repeat(n)` 等。 - **文件读写新方法**:如 `Files.writeString()` 和 `Files.readString()` [^8]。 ```java // 示例:Java 11 单文件执行 // 可以直接运行 java MyClass.java public class MyClass { public static void main(String[] args) { System.out.println("Hello from Java 11"); } } ``` ### 五、Java 12-14 新特性 这几个版本继续引入语言和工具链的小幅改进: - **Switch 表达式(Java 12/13)**:支持返回值和简化语法,使用 `->` 替代 `:`。 - **文本块(Java 13)**:使用 `"""..."""` 定义多行字符串。 - **模式匹配(instanceof 类型匹配)(Java 14)**:简化类型判断与转换 [^9]。 ```java // 示例:switch 表达式 int numLetters = switch (day) { case MONDAY, FRIDAY, SUNDAY -> 6; case TUESDAY -> 7; case THURSDAY, SATURDAY -> 8; case WEDNESDAY -> 9; }; ``` ### 六、Java 15-17 新特性 这些版本进一步推进语言现代化和性能优化: - **密封类(Sealed Classes)(Java 15/17)**:限制类或接口的继承关系,增强封装性。 - **移除实验性 AOT/JIT 编译器(Java 16)**。 - **记录类(Records)(Java 16)**:简化不可变数据类的定义。 - **模式匹配增强(Java 16)**:支持 `switch` 中的类型匹配。 - **强封装 JDK 内部 API(Java 16)**:限制访问内部 JDK 类。 - **Vector API(孵化阶段)(Java 16)**:支持 SIMD 指令优化。 - **结构化并发(Structured Concurrency)(Java 19)**:简化多线程编程模型(虽为 Java 19,但影响后续版本设计) [^10]。 ```java // 示例:record 类型 record Point(int x, int y) {} ``` ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值