java中static 和 final 关键字详解

本文深入解析Java中static和final关键字的使用场景与特性,包括静态成员、静态方法、常量属性及类加载机制。了解如何正确运用这些关键字,提升代码质量和效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

static 关键字
static 关键字属于一种修饰符,可以修饰成员属性,成员方法,内部类,代码块
不能修饰构造器和局部变量
使用static 修饰的成员称之为静态成员,没有static修饰的成员称之为普通成员
(1) 修饰属性:随着类加载而加载到方法区,所有对象共享的

a. 静态属性是所有对象共享的,一个对象更改,影响另外一个对象
   普通属性是对象独享的
b. 静态属性是随着类加载而加载(开辟空间),随着类的消亡而消亡,生命周期比较长
   普通属性随着对象消亡而消亡
c. 静态属性存储字方法区
   普通属性存储在堆中       
d. 静态属性使用类名.属性名调用,也可以使用对象.属性名调用,只是不推荐
   普通属性使用对象.属性名调用
e. 静态属性称之为类属性,普通属性是对象/实例属性
f. 设计层面:如果所有对象该属性都一样,这个属性就可以设置为静态属性,而且不轻易更改
   比如: PI, 银行利率,大部分是普通属性

(2) 修饰方法:静态方法

a. 静态方法和普通方法都是随着类的加载加载到方法区
b. 静态方法和普通方法都存储在方法区
c. 静态方法存储的时候参数列表没有this,所以不需要对象调用,只需要类名调用
   普通方法存储的时候参数有this,需要对象调用
d. 静态方法内只能直接调用静态成员,需要创建对象调用普通成员
    普通方法既可以调用静态成员也可以调用非静态属性
e. 当一个方法没用到普通成员的时候,可以把一个方法设计为静态方法,方便调用

(3) 静态成员特点

a. 静态成员类加载时候加载
b. 静态成员都是保存在方法区
c. 静态成员整个内存中只有一份
d. 静态成员和对象无关,可以直接使用类名调用
e. 静态成员都可以直接调用其他静态成员,但是不能直接调用普通成员,需要创建对象调用

final 关键字
final 关键字属于一种修饰符,可以修饰成员属性,成员方法,类,局部变量

(1) 修饰类:类不能被继承

final 修饰的类不能有子类,就是不能继承 ,所谓"太监类"
举例:String 类,使用final 修饰的类是基于安全考虑的,方法不被重写
一般自己定义的类不会使用final修饰符

(2) 修饰方法:方法不能重写

final 修饰的方法,不能被子类重写
但是子类是具有父类所有属性和方法的,只是不能改造父类final 修饰的方法的

(3) 修饰属性:就是常量不能修改
修饰属性的时候一般和static关键字一起使用

final 修饰特点:

a. 被final修饰的成员属性,就是常量,值不能更改
b. 被final 修饰的属性,就是常量,一般常量名一般大写,提高代码阅读性
c. 被fianl 修饰的属性,该属性必须要初始化,初始化地方包括声明变量或者构造器初始化
d. 一般来讲,static 经常和final 一起使用
例如:   public static final double PI = 3.14159265358979323846;
final 和static 一起使用的时候,首先俩个修饰符内容不冲突,而且虚拟机进行了优化并且调用比较方便

final + static 修饰属性虚拟机进行了优化:
就是调用该静态属性的时候,类不需要加载
本來静态属性调用的时候,类是会加载的

public class TestFinal {
    public static void main(String[] args) {
        //結果只输出了tom
        System.out.println(A.name);
    }
}

class A {
    //static final 修属性==常量 调用该常量的时候,类不需要被加载
    public static final String name = "tom";

    static {
        System.out.println("A类被加载了");
    }
}

(4) 修饰局部变量

被final修饰的局部变量,就是常量,值不能更改

java代码中也遵守就近原则

初始化代码块
类的四大成员之一,一般是隐式调用
语法:

  [static]{
  //有static修饰就是静态代码块 
  //没有static修饰就是普通代码块
  方法体
  }

作用:

a. 和构造器类似,都是初始化信息的
b. 当多个构造器有重复语句,可以将重复语句提取的初始化代码块中

静态初始化块只执行一次,普通代码块每次创建对象都执行一次

代码执行顺序
创建对象过程代码执行流程

 Student s = new Student()
第一步:  Student 类加载
第二步:  加载 Student类中的静态属成员(属性方法,代码块),加载顺序按照代码定义顺序
第三步:  加载 Student类中普通成员(属性,方法,代码块),加载顺序按照代码定义顺序
第四步:  加载构造器

一个类中加载顺序:

先静态成员--->普通成员---->构造器

如果该类有继承父类(非Object),对象创建过程中代码块执行流程:

 Student extends Person
 Student s = new Student()
第一步: Person类加载
第二步: 加载Person类的静态成员
第三步: 加载Student类的静态成员
第四步: 加载Person类的普通成员
第五步: 加载加载Person类的构造器
第六步: 加载 Student类中普通成员
第七步: 加载Student类的构造器

静态成员–>父类普通成员–>父类的构造–>子类的普通成员—>子类的构造器
静态成员随着类的加载而加载,所以静态成员先执行;
子类构造器执行前,先调用父类的构造器super(),所以先父类构造器在子类构造器之前执行;
普通成員相当与在构造器内代码的提取,所以先普通成员在构造器执行;

案例:结果-1
在这里插入图片描述
类的加载时机

a.  创建对象
b.  调用类的静态属性(不用final 修饰的时候)
c.  子类加载的时候,父类会先加载
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值