Java静态

本文详细解释了Java中的静态成员,包括静态变量的声明、特点、内存位置,静态方法的调用方式,静态代码块的作用,以及静态和非静态成员的访问差异。还介绍了类初始化的过程和静态导入的使用。
摘要由CSDN通过智能技术生成

1 静态关键字(static)

在类中声明的实例变量,其值是每一个对象独立的。但是有些成员变量的值不需要或不能每一个对象单独存储一份,即有些成员变量和当前类的对象无关。

在类中声明的实例方法,在类的外面必须要先创建对象,才能调用。但是有些方法的调用和当前类的对象无关,那么创建对象就有点麻烦了。

此时,就需要将和当前类的对象无关的成员变量、成员方法声明为静态的(static)。

代码里面有公共属性时候,避免冗余,可以使用静态生成一次,被多个对象去使用。

2 静态变量

1、语法格式

有static修饰的成员变量就是静态变量。

【修饰符】 class 类{
    【其他修饰符】 static 数据类型  静态变量名;
}
2、静态变量的特点
  • 静态变量的默认值规则和实例变量一样。

  • 静态变量值是所有对象共享。

  • 静态变量的值存储在方法区。

  • 静态变量在本类中,可以在任意方法、代码块、构造器中直接使用。

  • 如果权限修饰符允许,在其他类中可以通过“类名.静态变量”直接访问,也可以通过“对象.静态变量”的方式访问(但是更推荐使用类名.静态变量的方式)。

  • 静态变量的get/set方法也静态的,当局部变量与静态变量重名时,使用“类名.静态变量”进行区分。

  • 3、静态变量内存分析
  • 4、静态类变量和非静态实例变量、局部变量
  • 静态类变量(简称静态变量):存储在方法区,有默认值,所有对象共享,生命周期和类相同,还可以有权限修饰符、final等其他修饰符

  • 非静态实例变量(简称实例变量):存储在中,有默认值,每一个对象独立,生命周期每一个对象也独立,还可以有权限修饰符、final等其他修饰符

  • 局部变量:存储在中,没有默认值,每一次方法调用都是独立的,有作用域,只能有final修饰,没有其他修饰符

3 静态方法

1、语法格式

有static修饰的成员方法就是静态方法。

【修饰符】 class 类{
    【其他修饰符】 static 返回值类型 方法名(形参列表){
        方法体
    }
}
2、静态方法的特点
  • 静态方法在本类的任意方法、代码块、构造器中都可以直接被调用。

  • 只要权限修饰符允许,静态方法在其他类中可以通过“类名.静态方法“的方式调用。也可以通过”对象.静态方法“的方式调用(但是更推荐使用类名.静态方法的方式)。

  • 静态方法可以被子类继承,但不能被子类重写。

  • 静态方法的调用都只看编译时类型。

4 静态代码块

如果想要为静态变量初始化,可以直接在静态变量的声明后面直接赋值,也可以使用静态代码块。

1、语法格式

在代码块的前面加static,就是静态代码块。

【修饰符】 class 类{
    static{
        静态代码块
    }
}
2、静态代码块的特点

每一个类的静态代码块只会执行一次。

静态代码块的执行优先于非静态代码块和构造器。

3、静态代码块和非静态代码块

静态代码块在类初始化时执行,只执行一次

非静态代码块在实例初始化时执行,每次new对象都会执行

5 类初始化

(1)类的初始化就是为静态变量初始化。实际上,类初始化的过程时在调用一个<clinit>()方法,而这个方法是编译器自动生成的。编译器会将如下两部分的所有代码,按顺序合并到类初始化<clinit>()方法体中。

  • 静态类成员变量的显式赋值语句

  • 静态代码块中的语句

(2)每个类初始化只会进行一次,如果子类初始化时,发现父类没有初始化,那么会先初始化父类。

(3)类的初始化一定优先于实例初始化。

1、类初始化代码只执行一次
2、父类优先于子类初始化
3、类初始化优先于实例初始化

6 静态和非静态的区别

  • 静态成员可以是静态变量或静态方法。既可以通过对象名引用,也可以通过类名来引用
  • 非静态成员只能通过对象名引用。
1、本类中的访问限制区别

静态的类变量和静态的方法可以在本类的任意方法、代码块、构造器中直接访问。

非静态的实例变量和非静态的方法==只能==在本类的非静态的方法、非静态代码块、构造器中直接访问。

即:

  • 静态直接访问静态,可以

  • 非静态直接访问非静态,可以

  • 非静态直接访问静态,可以

  • 静态直接访问非静态,不可以

2、在其他类的访问方式区别

静态的类变量和静态的方法可以通过“类名.”的方式直接访问;也可以通过“对象."的方式访问。(但是更推荐使用类名的方式)

非静态的实例变量和非静态的方法==只能==通过“对象."方式访问。

3、this和super的使用

静态的方法和静态的代码块中,==不允许==出现this和super关键字,如果有重名问题,使用“类名.”进行区别。

非静态的方法和非静态的代码块中,可以使用this和super关键字。

7 静态导入

如果大量使用另一个类的静态成员,可以使用静态导入,简化代码。

import static 包.类名.静态成员名;
import static 包.类名.*;
package day0419.arrange_and_summarize.static02;

import static java.lang.Math.*;

/**
 * @ClassName TestStaticImport04
 * @Description TODO
 * @Author 周六
 * @Date 2024/4/20 13:45
 * @Version 1.0
 *
 * 导入:导包需要某个需要的类
 * import static java.lang.Math.*;
 *  import static 包.类名.*;
 * import static 包.类名.静态成员名;
 *  作用:简化代码
 *###  静态导入
 *
 * 如果大量使用另一个类的静态成员,可以使用静态导入,简化代码。
 *
 */
public class TestStaticImport04 {

    public static void main(String[] args) {
       /* System.out.println("圆周率:"+Math.PI);
        System.out.println("随机数"+Math.random());
        System.out.println("求根号"+Math.sqrt(8));*/


//静态导入Math包后,可以用以下写法
        System.out.println("圆周率:"+PI);
        System.out.println("随机数"+random());
        System.out.println("求根号"+sqrt(8));
    }
}

应用:

class Parent{
    public String name;
    public int age;


    public Parent() {
        System.out.println("无参构造");
    }
    public Parent(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("有参构造");
    }

    {
        System.out.println("父类的非静态代码区");
    }


    static{

        System.out.println("父类的静态代码区");

    }
    public  void eat(){
        System.out.println("父类的普通函数方法");
    }
}

class Baby1 extends Parent {
    public Baby1() {
        System.out.println("子类无参构造");
    }

    {
        System.out.println("子类的非静态代码区");
    }


    static{
        System.out.println("子类的静态代码区");

    }


    public Baby1(String name, int age) {
        super(name, age);
        System.out.println("");
    }

    @Override
    public void eat() {
        System.out.println("子类的普通函数方法");
        super.eat();
    }
    public static void main(String[] args) {
        System.out.println("main方法执行了");
     Baby1 baby1=new Baby1();
        baby1.eat();
       Baby1 baby11=new Baby1();
    }

}

public class TestStaticCodeBblock03 {
    public static void main(String[] args) {
        System.out.println("main方法执行了");
        Baby1 baby1=new Baby1();
        baby1.eat();
    }
}

输出:

父类的静态代码区
子类的静态代码区
main方法执行了
父类的非静态代码区
无参构造
子类的非静态代码区
子类无参构造
子类的普通函数方法
父类的普通函数方法
父类的非静态代码区
无参构造
子类的非静态代码区
子类无参构造

  • 22
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值