前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java中的final和static关键字详解

Java中的final和static关键字详解

作者头像
崩天的勾玉
发布2021-12-20 17:35:38
1.8K0
发布2021-12-20 17:35:38
举报
文章被收录于专栏:崩天的勾玉崩天的勾玉

这篇文章我们学习一下Java中final和static关键字的作用!

final

「修饰引用」

final关键字可以用来修饰引用、方法和类。

  1. 如果引用为基本数据类型,则该引用为常量,该值无法修改;
  2. 如果引用为引用数据类型,比如对象、数组,则该对象、数组本身可以修改,但指向该对象或数组的地址的引用不能修改。
  3. 如果引用时类的成员变量,则必须当场赋值,否则编译会报错。

「修饰方法」

当使用final修饰方法时,这个方法将成为最终方法,无法被子类重写。但是,该方法仍然可以被继承。

「修饰类」

当用final修改类时,该类成为最终类,无法被继承。简称为“断子绝孙类”。比如常用的String类就是最终类。

static

  1. 被static修饰的变量属于类变量,可以通过类名.变量名直接引用,而不需要new出一个类来
  2. 被static修饰的方法属于类方法,可以通过类名.方法名直接引用,而不需要new出一个类来

被static修饰的变量、被static修饰的方法统一属于类的静态资源,是类实例之间共享的,换言之,一处变、处处变。JDK把不同的静态资源放在了不同的类中而不把所有静态资源放在一个类里面,很多人可能想当然认为当然要这么做,但是是否想过为什么要这么做呢?个人认为主要有三个好处:

  1. 不同的类有自己的静态资源,这可以实现静态资源分类。比如和数学相关的静态资源放在java.lang.Math中,和日历相关的静态资源放在java.util.Calendar中,这样就很清晰了
  2. 避免重名。不同的类之间有重名的静态变量名、静态方法名也是很正常的,如果所有的都放在一起不可避免的一个问题就是名字重复,这时候怎么办?分类放置就好了。
  3. 避免静态资源类无限膨胀,这很好理解。

静态资源属于类,但是是独立于类存在的。从JVM的类加载机制的角度讲,静态资源是类初始化的时候加载的,而非静态资源是类new的时候加载的。类的初始化早于类的new,比如Class.forName(“xxx”)方法,就是初始化了一个类,但是并没有new它,只是加载这个类的静态资源罢了。所以对于静态资源来说,它是不可能知道一个类中有哪些非静态资源的;但是对于非静态资源来说就不一样了,由于它是new出来之后产生的,因此属于类的这些东西它都能认识。可知:

  1. 静态方法能不能引用非静态资源?不能,new的时候才会产生的东西,对于初始化后就存在的静态资源来说,根本不认识它。
  2. 静态方法里面能不能引用静态资源?可以,因为都是类初始化的时候加载的,大家相互都认识。
  3. 非静态方法里面能不能引用静态资源?可以,非静态方法就是实例方法,那是new之后才产生的,那么属于类的内容它都认识。

与非static的区别:

  • 在内存中存放的位置不同:所有static修饰的属性和方法都存放在内存的方法区里,而非静态的都存在堆内存中
  • 出现的时机不同:静态属性和方法在没创建对象之前就存在,而非静态的需要在创建对象才存在
  • 静态属性是整个类都公用的
  • 生命周期不一样,静态在类消失后被销毁,非静态在对象销毁后销毁
  • 用法:静态的可以直接通过类名访问,非静态只能通过对象进行访问

注意:

  • 带静态修饰符的方法只能访问静态属性
  • 非静态方法既能访问静态属性也能访问非静态属性
  • 非静态方法不能定义静态变量
  • 静态方法不能使用this关键字
  • 静态方法不能调用非静态方法,反之可以

「父子类中静态和非静态的关系:」

对于非静态属性,子类可以继承父类非静态属性;但是当父子类出现相同的非静态属性时,不会发生子类的重写并覆盖父类的非静态属性,而是隐藏父类的非静态属性。对于非静态方法,子类可以继承并重写父类的非静态方法。对于静态属性,子类可以继承父类的静态属性,但是如何和非静态属性一样时,会被隐藏。对于静态方法,子类可以继承父类的静态方法,但是不能重写静态方法,同名时会隐藏父类的。

注:静态属性、静态方法、非静态属性都可以被继承和隐藏,但是不可以被重写,非静态方法可以被重写和继承

static静态代码块

静态代码块只能写在类中方法外,不能写在方法中,它会随着类的加载而优先于各种代码块和构造方法的加载,并且只会加载一次,如果出现多个静态代码块,会按照书写顺序加载。

静态块也是static的重要应用之一。也是用于初始化一个类的时候做操作用的,和静态变量、静态方法一样,静态块里面的代码只执行一次,且只在初始化类的时候执行。

静态代码块是严格按照父类静态代码块->子类静态代码块的顺序加载的,且只加载一次。

「静态代码块的作用」

  • 一般情况下,有些代码需要在项目启动的时候就执行,这时候就需要静态代码块,比如一个项目启动需要加载配置文件,或初始化内容等。

对于普通方法:普通方法是需要加载类new出一个实例化对象,通过运行这个对象才能运行代码块,而静态方法随着类加载就运行了。对于静态方法:在类加载时静态方法也加载了,但是必须需要类名或者对象名才可以访问,相比于静态代码块,静态方法是被动运行,而静态代码块是主动运行

注意:静态代码块不能出现在任何方法体内。静态代码块不能访问普通变量,普通变量只能通过对象调用的,所以普通变量不能放在静态代码块中

执行顺序:「静态代码块>构造代码块>构造函数>普通代码块」

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-09-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 崩天的勾玉 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • final
  • static
  • static静态代码块
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档