Re: [问题] 建构子与static 变量

楼主: kyleJ (资工人)   2016-07-14 00:16:01
※ 引述《birdy1147 (Allen)》之铭言:
: 不好意思,想问个比较基础的问题,我知道题意是要考static与 non-static,但我看了
: 很久都想不通,如下:
: class Ans{
: int ns;
: static int s;
: Ans(int ns){
: if(s<ns){
: s=ns;
: this.ns=ns;
: }
: }
: void print( ){
: system.out.println(“ns= ”+ns+“ s= ”+s);
: }
: }
: public class Test{
: public static void main(String[ ] args){
: Ans a = new Ans(50);
: Ans b = new Ans(125);
: Ans c = new Ans(100);
: a.print( );
: b.print( );
: c.print( );
: }
: }
: 我以为结果会是 ns=50 s=50
: ns=125 s=125
: ns=100 s=100
: 但结果是 ns=50 s=125
: ns=125 s=125
: ns=0 s=125
: 我知道全域变量int在没有设定的情况下,系统会默认为0
: 所以在new Ans(50);时,经过if判断式,会被两个变量设为50
: 所以我以为答案是我想的那样,
: 但从正确答案看来,static int s;会留着之前的50,而int ns;却会重新归0
: 想请问这是为什么呢?我以为重新new过以后,指派给新的物件,应该会是不相关的两个
: 物件?
你从结果推测出的想法是对的,
static field会留下来,instance的field才会重来。
首先,你知道全域变量的话,我猜你可能学过C之类的语言吧?
但在Java中不管是static field还是物件的field都不叫做全域变量,
field在中文有些人翻译成“成员变量”。
不只是开发者取的名字不一样而已,而是连本质都不一样。
首先讲non-static field这部分跟你说的一样,
每new一次就会指派新的内存空间来存放,
所以每个新产生出来的物件内的变量都不会干扰。
再来是static的部分,我想这部分你误会了,
以你的叙述来看,应该是把他当成了跟物件内成员变量一样,
每new一个就会有一个独立的空间,互不干扰吧?
但这样不就会变得跟non-static field一样了吗?
又何必分成两种呢?
static的特点是“在内存中只有一个”,
而且“不用new,打从一开始就存在”。
所以你才会看到变量s的内容一直没改变。
我不知道你的程式码是哪里来的,
但那样会令人不好理解static与non-static的差别。
我再写个简单的范例给你看看两者个差别。
public class Test{
private static int count; // 纪录数量
private int number; // 纪录自己的号码
public Test(int num){
number=num;
count++;
}
public void print(){
System.out.println("我是"+number
+"号,目前加上我已产生"+count+"跟我一样的物件");
}
public static void main(String[] args){
new Test(20).print();
new Test(30).print();
new Test(50).print();
}
}
编译后会输出:
我是20号,目前加上我已经产生了1个跟我一样的物件
我是30号,目前加上我已经产生了2个跟我一样的物件
我是50号,目前加上我已经产生了3个跟我一样的物件
你会看到我们new了三个Test类别所产生的物件,
三个物件都记得自己被赋予的number。
但count则不一样,count变量是static的,
不管new了几次都是共用一个内存位置。
所以每呼叫一次就会在建构子内将原本的数字加一,
运用这个特性就产生了纪录有几个Test物件的效果。
作者: smallmac (洨麦克)   2016-07-14 13:54:00
推讲解
作者: quadro (屎凯)   2016-07-14 14:03:00
number=num;
作者: birdy1147 (Allen)   2016-07-15 18:35:00
谢谢,你解释得很清楚,我有比较懂了
作者: charlie1081 (神奇萨满)   2016-07-28 12:10:00
长知识了谢~
作者: poolongkong (普拢贡)   2016-07-30 12:19:00
补充一点,static连宣告都不用就会存在,可以试试看在第一行直接print static变量,并不会有errorTest.count啊 不过好像需要给初始值
作者: ssccg (23)   2016-07-31 04:26:00
local变量才需要初值,instance、static都有默认值

Links booklink

Contact Us: admin [ a t ] ucptt.com