• ベストアンサー

静止的フィールドについて教えてください

教えてください。以下のプログラムだとして、 class Box { static int a = 0 ; int b = 0 ; int c = a+4; } class sample { public static void main(String[] args) { Box n = new Box() ; n.a-- ; n.b-- ; n.c[1]-- ; System.out.println("n.a= "+n.a);//-1 System.out.println("n.b ="+n.b);//-1 System.out.println("n.c[2]="+n.c[2]);//4 Box m = new Box() ; m.a++ ; m.b++ ; m.c[2]++ ; System.out.println("n.a ="+n.a);//0 System.out.println("n.b ="+n.b);//-1 System.out.println("n.c[2] ="+n.c[2]);//4 System.out.println("m.a ="+m.a);//0 System.out.println("m.b ="+m.b);//1 System.out.println("m.c[2] ="+m.c[2]);//4 } } Box nの中のn.aの値はわかります。 ですが、Box mの中のn.aは、a がstaticフィールド(?)なので元の0に戻りますが、m.aがなぜ0なのかわかりません。 そもそもstatic int = ●; のときは、静止的intと教わったのですが、どういう現象が起こるのかいまいちです。 よろしくお願いします。

noname#85912
noname#85912
  • Java
  • 回答数5
  • ありがとう数4

質問者が選んだベストアンサー

  • ベストアンサー
  • sh_hirose
  • ベストアンサー率66% (56/84)
回答No.5

まだ間違いがある・・・; こんなんかな? class Box {  static int a = 0 ;  int b = 0 ;  int c[] = {1, 3, a+4}; } class sample {  public static void main(String[] args) {   Box n = new Box() ;   n.a--;   n.b--;   n.c[1]--;   System.out.println("n.a= "+n.a);   System.out.println("n.b ="+n.b);   System.out.println("n.c[2]="+n.c[2]);   Box m = new Box() ;   m.a++;   m.b++;   m.c[2]++;   System.out.println("n.a ="+n.a);   System.out.println("n.b ="+n.b);   System.out.println("n.c[2] ="+n.c[2]);   System.out.println("m.a ="+m.a);   System.out.println("m.b ="+m.b);   System.out.println("m.c[2] ="+m.c[2]);  } } 処理を追いながら中身の値を確認します。 Box n = new Box(); // n.a = 0, n.b = 0, n.c[0] = 1, n.c[1] = 3, n.c[2] = a + 4 = 4 // m.a = 0, m.b = なし, m.c[0] = なし, m.c[1] = なし, m.c[2] = なし // mはインスタンスが生成されていないのでstatic以外のフィールドは存在しません。 // staticのフィールドはプログラムが実行されたときに1つだけメモリ領域を確保するのでm.aには値がある。 n.a--; // n.a = -1, n.b = 0, n.c[0] = 1, n.c[1] = 3, n.c[2] = 4 // m.a = -1, m.b = なし, m.c[0] = なし, m.c[1] = なし, m.c[2] = なし // n.aとm.aは同じメモリ領域なのでn.aをデクリメントするとm.aもデクリメントされたように見える。 n.b--; // n.a = -1, n.b = -1, n.c[0] = 1, n.c[1] = 3, n.c[2] = 4 // m.a = -1, m.b = なし, m.c[0] = なし, m.c[1] = なし, m.c[2] = なし n.c[1]--; // n.a = -1, n.b = -1, n.c[0] = 1, n.c[1] = 2, n.c[2] = 4 // m.a = -1, m.b = なし, m.c[0] = なし, m.c[1] = なし, m.c[2] = なし Box m = new Box(); // n.a = -1, n.b = -1, n.c[0] = 1, n.c[1] = 2, n.c[2] = 4 // m.a = -1, m.b = 0, m.c[0] = 1, m.c[1] = 3, m.c[2] = a + 4 = 3 // インスタンスが生成されたのはmだけなのでnの値は変化しない。 m.a++; // n.a = 0, n.b = -1, n.c[0] = 1, n.c[1] = 2, n.c[2] = 4 // m.a = 0, m.b = 0, m.c[0] = 1, m.c[1] = 3, m.c[2] = 3 // n.aとm.aは同じメモリ領域なのでm.aをインクリメントするとn.aもインリメントされたように見える。 m.b++; // n.a = 0, n.b = -1, n.c[0] = 1, n.c[1] = 2, n.c[2] = 4 // m.a = 0, m.b = 1, m.c[0] = 1, m.c[1] = 3, m.c[2] = 3 m.c[2]++; // n.a = 0, n.b = -1, n.c[0] = 1, n.c[1] = 2, n.c[2] = 4 // m.a = 0, m.b = 1, m.c[0] = 1, m.c[1] = 3, m.c[2] = 4 >そしてBox mのn.c[2]+m.c[2]の答えが8でした。 >なぜ9じゃなくて8なんだろう?と疑問です・・・ まずint c[] = {1, 3, a + 4}の処理が行われるのはインスタンスが生成されたときです。(このときにa + 4の計算が行われます。) つまりnew Box()のとき。 インスタンスの生成後、aの値を変化させてもa + 4の処理は行われないのでn.a--;やm.a++;を行ったとしてもn.c[2]、m.c[2]の値は変化しません。 こんな説明でどうでしょう?

noname#85912
質問者

お礼

ミスが多くてすいません>< 再びご回答ありがとうございます。ようやくわかりました。 わかりやすいご説明感謝します。

その他の回答 (4)

回答No.4

staticな値はクラスで一つしか存在しないため、新たにオブジェクトを生成しても、演算する値を同じになります。 class Stat{ static int value 10; } class Test{ Stat stat_a = new Stat(); stat_a.value = 15; Stat stat_b = new Stat(); System.out.print(stat_b.value); } これで標準出力した場合、「15」と出力されるということです。 どうでしょうか?

noname#85912
質問者

お礼

わかりやすいご説明、ご回答ありがとうございます! 参考にさせていただきます。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

何の話なのかわからないので, 「きちんと動作するプログラム」を書いてください. あと, JAVA だからファイル名も. じゃないと, 憶測で答えるしかできないので, はっきりいって「時間の無駄」です.

  • sh_hirose
  • ベストアンサー率66% (56/84)
回答No.2

まずBoxクラスのcは配列ではないので n.c[1]--; System.out.println("n.c[2]=" + n.c[2]); などは行えません。 staticの説明はNo.1の方が言っているとおりです。 static int aはプログラム全体で1つしか作成できず、プログラムが起動されたときに作成されます。(厳密にはどのタイミングかはわかりませんが・・・。) メモリ領域が1つしか確保されないってことです。 int bはインスタンス毎に作成され、インスタンスを作成するたびに作成されます。 new Box()を行うごとに新しくメモリ領域が確保されます。 メモリ領域イメージ |a|n.b|n.c|m.b|m.c|・・・ つまりn.aとm.aは同じメモリ領域を読み込んでいるので同じ値となります。 Box n = new Box(); // n.a=0,n.b=0, m.a=0, m.b=存在しない n.a--; n.b--; // n.a=-1, n.b=-1, m.a=-1, m.b=存在しない Box m = new Box(); // n.a=-1,n.b=-1, m.a=-1, m.b=0 m.a++; m.b++; // n.a=0,n.b=-1, m.a=0, m.b=1 となります。

noname#85912
質問者

補足

ご回答ありがとうございます。 すいません;; int cを略しすぎました。 int c={1,3,a+4} です。 そしてBox mのn.c[2]+m.c[2]の答えが8でした。 なぜ9じゃなくて8なんだろう?と疑問です・・・

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

このコード, コンパイルできないと思うんだが気のせいか? さておき static なフィールドはクラスの全てのインスタンスで共有されます (かつインスタンスなしでアクセスできる). だから m.a と n.a は「同じもの」です.

noname#85912
質問者

お礼

ご回答ありがとうございます。 すいません;; int cを略しすぎました。 int c={1,3,a+4} です。 そしてBox mのn.c[2]+m.c[2]の答えが8でした。 なぜ9じゃなくて8なんだろう?と疑問です・・・

関連するQ&A

  • 出力結果が得られる理由が分かりません

    一つ目のプログラムソース: public class Array{ public static void main(String[] args){ int[] a={1,2,3,4}; int[] b={5,6,7,8}; System.out.print(a[2]); System.out.print(b[2]); b=a; System.out.print(a[2]); System.out.print(b[2]); b[2]=0; System.out.print(a[2]); System.out.print(b[2]); } } 出力結果:  373300 二つ目のプログラムソース: class Box{ private int value; public Box(){value=0;} public Box(int v){setValue(v);} public void setValue(int v){value=v;} public int getValue(){return value;} public Box copy(){ Box b=new Box(); b.setValue(getValue()); return b; } } public class BoxTest{ public static void main(String[] args){ Box x=new Box(1); Box y=new Box(2); Box z=new Box(3); x=z.copy(); y=z; System.out.print(x.getValue()); System.out.print(y.getValue()); System.out.println(z.getValue()); System.out.println(x==y); System.out.println(y==z); System.out.println(z==x); } } 出力結果:  333 false true false この二つのプログラムがどうしてこのような出力結果になるのかが分かりません。 良かったら教えてください。

    • ベストアンサー
    • Java
  • privateなフィールドは継承されない?

    たとえば、 class A { private int width; public A(){ this.width=3; } public int getWidth(){ return width; } public void setWidth(int width){ this.width=width; } } -------------------------------- class B extends A { String name; public B(){ this.name="あきら"; } } -------------------------------- class TestAB{ public static void main(String[] args){ B b = new B(); B b2= new B(); System.out.println(b.getWidth()); b2.setWidth(5); System.out.println(b2.getWidth()); System.out.println(b.getWidth()); } } というのがあったとして、ある参考書では「privateなフィールドは継承されない」と書いてありました。 でも、これってwidthに直接アクセスして値を変更できないだけであって、 widthは継承されてるのではないですか? B型のb専用、b2専用のwidthがあるのではないですか? ちょっと頭がこんがらがってきました。。

    • ベストアンサー
    • Java
  • javaハノイの塔について

    public class hanoinotou { static void move(int n,int a,int b , int c) { if(n>1) move(n-1,a,c,b); System.out.println("円盤"+n+":"+a+"→"+c); if(n>1) move(n-1,b,a,c);} public static void main(String args[]){ move(3,1,2,3); } } ↑このプログラムの動き方を教えてください よろしくお願いします

  • synchronizedが解りません。

    synchronized( a ) { a.add(); } ブロック文で aオブジェクトをロックしてるはずなんですが 結果を見ると出来てないようです なぜうまくいかないんでしょうか? 教えてください。 class Test extends Thread { feet a = new feet(); public static void main( String args[] ){ for( int i = 0; i < 3; i++ ){ Test b = new Test(); b.start(); } } public void run() { synchronized( a ) { a.add(); } } } class feet{ int n, m; void add(){ n++; System.out.println( n + " " + m ); try { Thread.sleep( 1000 ); }catch( InterruptedException err ){ } m++; System.out.println( n + " " + m ); } }

    • ベストアンサー
    • Java
  • Javaの計算について

    Java初心者です。以下の問題で、c = 10になるのか判りません。括弧が先に計算されるのではないのでしょうか?どなたか解説していただけませんでしょうか? public class M{ public static void main(String[] args){ int a = 5; int b = (a = 2) * a; a = 5; int c = a * (a = 2); System.out.println("b = " + b + " c = " + c); } }

    • ベストアンサー
    • Java
  • 配列の変換について

    こんにちは、お世話になります。 次のコードで、どうしてint[] i = {1,2,3};が int[] i = new int[3]; int[0] = 1; int[1] = 2; int[2] = 3; のようになるのか分かりません。お分かりの方よろしくお願いします。 class arr{ public static void main(String[] args){ String[] name = new String[3]; name[0] = "1番目"; name[1] = "2番目"; name[2] = "3番目";      System.out.println("nameの0:" + name[0]); System.out.println("nameの1:" + name[1]); System.out.println("nameの2:" + name[2]); int[] i = {1,2,3}; System.out.println("iの0:" + i[0]); System.out.println("iの1:" + i[1]); System.out.println("iの2:" + i[2]); char c[] = new char[1]; c[0] = 'A'; System.out.println("cの0:" + c[0]); } }

  • コンストラクタについて

    これも試験問題らしくて自分でやってみましたのであってるかどうか自信なくて どなたかみてみていただけたらと思います.よろしくお願いします。 下のソースファイルをコンストラクタを用いたものに修正しなさい class Sconst{ int x,y,z; void print(){ System.out.println(x); System.out.println(y); System.out.println(z); } } class ExConstTest{ public static void main (String[] args ){ Sconst sc=new Sconst(); sc.x=10; sc.y=30; sc.z=5; } } ------------------------------------------------------------- class Sconst{ int x,y,z; Sconst(){ x=10; y=30; z=5; } } class ExConstTest{ public static void main (String[] args ){ Sconst a1; Sconst a2; Sconst a3; a1=new Sconst(); a2=new Sconst(); a3=new Sconst(); System.out.println(a1.x); System.out.println(a2.x); System.out.println(a3.x); } }

    • ベストアンサー
    • Java
  • 例外処理について

    続けて質問です…すみません; public class OddEven { private static boolean even(int k) { return k/2*2 == k; } public static void main(String[] args){ int l; int m=0; int n=0; try{ for(l=0;l<args.length; l++) { int a = Integer.parseInt(args[k]); if(even(a)) { m++; } else{ n++; } } }catch (NumberFormatException e) { System.out.println("<" + e + ">"); } System.out.println("Even = " + m); System.out.println("Odd = " + n); } } とし、例えば「1 2 3 a 5」の中の偶数奇数の個数を判定すると、奇数が2個、偶数が1個となり、例外処理されたaの後の5が奇数にカウントされないのですが、どのように修正すればよろしいのでしょうか?

    • ベストアンサー
    • Java
  • java

    次のコード中の括弧内で下に示す11通りの各コードを実行した場合の実行画面を正確に答えよ。 class A{ public void func1(){System.out.println("A1");} public void func2(){System.out.println("A2");} } class B extends A{ public void func1(){System.out.println("B");} } class C{ public int x=0, y=1; } class D extends C{ public int x=2; public void func1(int x){System.out.println(x);} public void func2(int x){System.out.println(this.x);} public void func3(int x){System.out.println(super.x);} public void func4(int x){System.out.println(this.y);} public void func5(int x){System.out.println(super.y);} } class E{ public void func1(int n){ try{ System.out.println("E1"); int[] ary=new int[n]; System.out.println("E2"); }catch(NegativeArraySizeException e){ System.out.println("E3"); }finally{ System.out.println("E4"); } } } (1) A a=new A(); a.func1(); (2) A a=new B(); a.func1(); (3) B b=new B(); b.func1(); (4) B b=new B(); b.func2(); (5) D d=new D(); d.func1(3); (6) D d=new D(); d.func2(3); (7) D d=new D(); d.func3(3); (8) D d=new D(); d.func4(3); (9) D d=new D(); d.func5(3); (10) E e=new E(); e.func1(5); (11) E e=new E(); e.func1(-2); (1) A1 (2)B (3)B (4) A2 (5) 3 (6) 2 (7) 0 (8) 1 (9) 1 (10) E1E2E4(11) E1E3E4 と答えになるんですがなぜこうなるのかわかりません。教えてください

    • ベストアンサー
    • Java
  • forループの中での初期化

    http://www.okweb.ne.jp/kotaeru.php3?q=802781 すいません。またわからなくなってしまいました。 class Fooo{   public static void main(String args[]){     int a;     int b=10;     int c;     for(int i=0;i<5;i++){       a=10;       c=b+i;       System.out.print(c);     }     System.out.println(a);   } } 初期化は「確実に」行われていますよね? aが初期化されてない、というコンパイルエラーが出るのです・・・ なぜですか???

    • ベストアンサー
    • Java