类的高级概念 --- static关键字

本文深入解析了Java中static关键字的使用,比较了static属性与非static属性的内存差异、访问方式,以及static方法与非static方法的设计原则。特别强调了常量和工具方法为何适合static修饰,并揭示了static初始化块的独特之处。
摘要由CSDN通过智能技术生成

static

static关键字 -- 是一个可选修饰符,它本身的含义叫做“静态”。 它不仅只能修饰方法,它也可以修饰:属性、代码块、内部类 。不能修饰构造方法。

static 与 非static 的属性

在一个类当中,属性也可以选择使用static进行修饰。 

一、语法上的对比:

有static

1、有static修饰的属性可以用"类名."的方式直接访问,也可以通过“对象.”的方式进行访问(但第二种方式,不推荐)。

2、用static修饰的属性,是全类的所有对象共享一个值,无论是该类的哪个对象把这个值改了,那么大家的值都跟着变。

非static

1、非static修饰的属性是只能用“对象.”的方式访问;  

2、非static修饰的属性是每个对象身上有一个该属性的变量,存放了该对象该属性的值。

        从两者的第2点语法对比,我们领会Java语法设计者的设计意图。之所以让static修饰的属性能够用“类名.”的方式去访问,不是为了让我们方便,而是为了体现这个属性是全类共享的。而非static修饰的属性用"对象."的方式去访问,是为了清楚的表达到底要操作是哪个对象的该属性。 在一个类当中,能够用static修饰的属性是不多见的,通常都需要在某个特定的问题域限制当中才找得到。static才是特例,通常都是非static的属性。

根据经验,只有常量,我们能够不动脑袋直接设计为static

原因:

1、常量属性的值是在类的定义中给定的,每个对象身上都是同样的值(常量也不能改);所以没有必要在每个对象身上存放一份,只需要全类共享一个就可以了。

2、常量属性的值在类定义中给定以后,外部也没有更改的权利,所以可以不用保密,直接public公布给外部看;

3、所以,通常常量属性的修饰符是:public static final的。

千万不要为了方便去把属性设计为static,一定要找到全类共享一个值的属性才做这种设计。

二、内存上的区别:

1、存放的位置不同

非static修饰的属性是在对象本身身上,也就是在堆当中; static修饰的属性没有存在对象身上,也就不是在堆当中;而是单独作为类的共享信息存放在一个叫做“静态区”的内存空间里;一个类的一个static属性只划分一个存放空间。

2、该属性在内存中产生的时机不同

非static属性实在产生对象的时候,在内存中产生

static的属性是在 加载期 产生与内存中

两个凡是:

1、凡是用static修饰的内容,都是表示它与对象无关,只与类相关; 所以:用static修饰的属性,我们又叫做“类属性”/“静态属性”, 没有static修饰的属性,我们一般叫做“成员属性”

2、凡是用static修饰的内容,都会在加载期加载并执行。

static 和 非static修饰的 方法

一、在语法上的对比:

有static的方法:

1、在调用该方法的时候,可以通过“类名.”的方式来访问,也可以通过"对象."的方式来访问;只不过第2种方式不推荐,但不会报错;

2、在方法的内部实现中,静态方法只能调用本类的静态属性 或 静态方法; 之所以不能调用的原因:

原因1:静态方法是通过"类名."的方式调用,这个时候方法内部是没有当前对象这一目标,也就是说没有“this”,所以无法确认这里访问的非静态属性或方法到底是哪个对象的。 --- 这是站在面向对象的设计思想来表达的;

原因2:当我们在进行类的编译和加载的时候,在进行加载的顺序划分时,JVM都是首先加载静态的,然后再加载非静态的。如果在加载静态内容时,发现里面有非静态的调用,这个时候JVM是不认识这些非静态内容的,因此报错。反过来,在加载非静态的方法时,由于静态内容已经加载过了,所以JVM认识,因此通过。

非static的方法:

1、在调用该方法的时候,只能通过“对象.”的方式访问。

2、在方法的实现内部,即可以操作本类的静态属性和静态方法,也可以调用到本类的非静态属性和非静态方法;

这样的设计同样表明了用static修饰的方法是跟对象无关的;非static的方法是一定要确定到底是哪个对象去做这件事情。所以,用static修饰的方法又被称之为“类方法”或“静态方法”;非static修饰的方法被称为“成员方法”。

二、设计上的区别:

我们要把工具类的工具方法,设计为static的;其他的都是非static的。

static 一定不能用来修饰 构造方法

因为构造方法就是用来创建对象的,而static天生就是用来表示与对象无关。

static 和 非static修饰 初始化块

对初始化块的简单认知

初始化块的语法非常简单,就是直接在类里面,打上一对"{}",然后在"{}"里面书写代码。

它从外观形式上非常像一个没有方法声明,只有方法实现的特殊语句块。在它内部,我们可以书写任意指令语句,包括:输入输出、变量声明、运算表达、流程控制; 由于这个代码块是没有方法声明的,也不能接受参数和返回,所以很明显它是不能够在类的外部随意调用的。 它的执行只能是在一个特定的时间点运行。 什么时候呢? 产生对象的时候,所以它也被称之为“实例初始化块”。每产生一个对象,就会被执行一次。

初始化块也分static 和 非static的

前者也叫“静态初始化块”,后者叫做“实例初始化块”

"静态初始化块"是在加载类的时候被执行的,而一个类在JVM当中只需要加载一次,所以它是首先被执行,且以后无论产生多少对象,甚至不产生对象,也不再被执行。 “实例初始化块”是在产生对象的时候被执行,且产生多少个对象就会被执行多少次。

如果说“实例初始化块”的执行时机和次数与构造方法有一定的重叠,导致它的使用量很少。但是“静态初始化块”由于其独特的执行时机和执行次数,导致它是没有被替换的可能的。

很多资源的操作,包括开启呀,预加载呀,都是一次性完成的,没有必要每new一个对象就做一次,而且很多时候我们会把做这些动作放到程序的加载期而不是运行期,这是为了提升程序的运行速度。

静态初始化块也满足两个凡是:

1、与类有关;

--- 类加载的时候被执行

与对象无关;

--- 不能在其内部访问对象的非静态内容,没有this当前对象,与产生对象与否无关。

2、凡是用static修饰的内容,都会在加载期加载并执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值