分享
 
 
 

Static 的意义与实作方式

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

「将某 class 产生出一个 instance 之后,此 class 所有的 instance field 都会新增一份,那么所有的 instance method 是否也会新增一份?」我常常看到网路上有人在讨论此问题,所以写了这篇文章,以为解释。

Member 的种类

类别(class)的内部组成统称为成员(member),如果依据成员是「资料」还是「程式」来区分,可以分成:

资料,被称为 field

程式,被称为 method

如果再依据有无使用static修饰而细分,则成员可细分成四种:

class field:有用static修饰的field

class method:有用static修饰的method

instance field:没有用static修饰的field

instance method:没有用static修饰的method

顾名思义,class field/method和class本身有密切的关系,而instance field/method则与instance(也就是物件)有密切的关系。请看下面的范例程式。

public class Class1 {

public static int classField;

public static void classMethod1() {

// ...

}

public static void classMethod2() {

// ...

}

public int instanceField;

public void instanceMethod1() {

// ...

}

public void instanceMethod2() {

// ...

}

}

public class Class2 {

public static void classMethod () {

// ...

}

public void instanceMethod() {

// ...

}

}

Field

宣告field时,如果前面加上static的修饰字,就会使得此field变成是class field。一个class field永远只占用一块记忆体,而且此记忆体空间是在此class一被载入(load)记忆体之后就立刻配置的(allocate),感觉就如同此field与该class本身相关,而不是与该class的instance相关。class field可以被同一个class的class method内部所直接使用,举例来说,上述的classMethod1()内部可以出现classField。如果Class1的class method或instance method欲使用到Class2的class field,就必须在前面冠上Class2,例如:Class2.classField。

宣告field时,如果前面「不」加上static的修饰字,就会使得此field变成是instance field。对instance field而言,每产生一个instance(物件)就多一块instance field的记忆体,每少一个instance就少一块instance field的记忆体。instance field可以被同一个instance的instance method内部所直接使用,举例来说,上述的instanceMethod1()内部可以出现instanceField。如果某class的class method或instance method欲使用到某instance的instance field,就必须在前面冠上instance名称,例如:obj.classField。

Method

宣告method时,如果前面加上static的修饰字,就会使得此method变成是class method。对class method而言,永远只占用一块记忆体,而且此记忆体空间是在此class一被载入进记忆体之后就立刻配置的,就如同此method是与该class本身相关,而不是与该class的instance相关。class method可以被同一个class的任何class method内部所直接使用,举例来说,上述的classMethod1()内部可以出现classMethod2()。如果Class1的class method或instance method欲使用到Class2的classMethod(),就必须在前面冠上Class2,也就是Class2.classMethod()。

宣告method时,如果前面「不」加上static的修饰字,就会使得此method变成是instance method。对instance method而言,每产生一个instance「并不会」多一块instance method的记忆体。同一个method不管被调用(invoke)几次,也不管被调用时的instance是何者,每次的程式码完全都一样,差别只在每次执行时资料不同,而资料是存放在call stack中,所以不会混淆。在instance method内,资料的来源包括了参数和instance field。参数被传进来变成call stack内的entry,所以不会混淆,这很容易理解,但是instance field是如何区隔开来的(前面刚提过:instance field会随着instance数目增加而增加),这是透过隐匿(implicit)的this参数来达到了,稍后会有说明。instance method可以被同一个instance的instance method内部所直接使用,举例来说,上述的instanceMethod1()内部可以出现instanceMethod2()。如果某class的class method或instance method欲使用到某instance的某instance method,就必须在前面冠上此instance名称,例如:obj.classMethod()。

隐匿的 this 参数

综合上面的叙述来看:

class field:共用一块记忆体

class method:共用一块记忆体

instance field:随着每个instance各有一块记忆体

instance method:共用一块记忆体

instance method为什么不是随着每个instance占有一块记忆体,反倒是共用一块记忆体?其实,让每个instance method如同instance field一样,随着每个instance占有一块记忆体,这么做当然是可以的,只是Java编译器和JVM都不这么做,因为太浪费记忆体空间了。一个field少则占用一个byte,多则占用数百Byte,但是method少则数个byte,多则数百Kilo Byte。Mehtod耗费的记忆体是field的数百倍,甚至数千倍,当然是能共用就尽量共用,比较不会消耗记忆体。既然JVM让一个class的所有instance共用相同的instance method,下面两行程式码在instanceMethod()内部时,如何区分是instance1或instance2?

instance1.instanceMethod();

instance2.instanceMethod();

因为编译器会帮我们在把instance1和instance2个别传入instanceMethod()中当作第一个参数。也就是说,任何instance method参数的实际个数都会比表面上多一个,这个多出来的参数是由Java编译器帮我们加上去的,用来代表对应的instance。此参数的变数名称为this,也是Java的一个关键字(keyword)。

当调用某个instance method或使用某个instance field时,你必须在前面加上该instance的名称,如果该instance method/field相关的instance和当时程式码所在的instance method的instance指的是同一个instance时,该instance的名称就是this,这种情况下,你也可以选择不在前面加上「this.」。

然而,在某些状况下,非得在前面加上「this.」不可。例如,当method中的参数或区域变数和instance field名称完全相同时,如果不在前面冠上「this.」,那么指的是参数或区域变数;如果在前面冠上「this.」,那么指的才是instance field。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有