Javaの変数スコープについての疑問

このQ&Aのポイント
  • Javaの変数スコープに関して分かりにくい点があります。
  • プログラムを実行すると最後の値が15ではなく20になる理由が分からないです。
  • どなたか教えて頂けないでしょうか。
回答を見る
  • ベストアンサー

Javaの初歩

変数のスコープみたいなものが、いまだに良く分かって ないみたいなんです。このプログラムを実行すると、 15 0 20と表示されるのですが、最後がなぜ15ではなく て、20なのかがなかなか分かりません。どなたか教えて 頂けませんでしょうか。お願いします。 class Value { public int i = 15; } public class Test { public static void main(String argv[]) { Test t = new Test(); t.first(); } public void first() { int i = 5; Value v = new Value(); v.i = 25; second(v, i); System.out.println(v.i); } public void second(Value v, int i) { i = 0; v.i = 20; Value val = new Value(); v = val; System.out.println(v.i + " " + i); } }

  • Java
  • 回答数2
  • ありがとう数1

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

  • ベストアンサー
  • ranx
  • ベストアンサー率24% (357/1463)
回答No.2

> 参照先が変わらない限 > り、引数の値を変更し、main()に反映する事が出来ると > 考えてよろしいのでしょうか? 「引数の値」というのが意味不明です。 例えば質問文章中のプログラムの場合、second()メソッドは Valueクラスの変数を引数にとります。この引数の値とは、 とりも直さずその「参照」そのものに他なりません。 その値を変更するということは、参照先を変更することと 同義であるはずです。メソッドの中で参照先を変更しても、 それはメソッドの外には影響しません。呼び出し側の変数の 参照先は元のまま残ります。 メソッドの外に取り出せるのは、 「引数で参照されているインスタンスのメンバーの値」です。 これはいわばグローバル変数のようなもので、VMの中に おいてユニークな存在と考えて構いません。メソッドの 呼び出し側だろうと呼び出された側だろうと、その値は 同時にはただ一つです。 答えになったでしょうか。

northcurlcurl
質問者

お礼

再度の回答ありがとうございます。「引数の値」という のは、”メソッドに引数として渡された、参照型変数の 値”、という意味です。説明不足で申し訳ございません でした。ranxさんの説明を何回も注意深く読んでいるう ちに、理解出来たような気がします。ありがとうござい ました。

その他の回答 (1)

  • ranx
  • ベストアンサー率24% (357/1463)
回答No.1

質問に対する直接の回答は、メソッドsecond()の中で20という値を代入しているからだと いうことになると思いますが、質問者の疑問は恐らくメソッドに値で渡された引数に代入 された値がなぜメソッドの外部に影響するのかということだと思います。 「参照型」に対する理解を深める必要があると思います。Javaにおける変数の型は、大きく 分けて二通りあります。「プリミティブ型」と「参照型」です。前者はintとかcharといった 基本的な型で、void、boolean、byte、char、short、int、long、float、doubleの9種類 しかありません。それ以外はすべて参照型と呼ばれるものになります。これは他の言語、 例えばCなどで「ポインタ」と呼ばれるものに相当すると考えて間違いありません。 つまり、変数とは別のところに実体があって、変数はそれを指し示す・参照するものとして 定義されます。変数だけでは実体が無いのです。では実体はどこで作られるかというと、 これを作るのが「new」という演算子です。newした時点で実体(インスタンス)が作成され、 それを「参照する」ものが変数に入れられるのです。これをメソッドの引数として使ったら どうなるか。実体を「参照するもの」がコピーされてメソッドに渡されます。しかし、 参照される実体(インスタンス)は元のままです。呼び出されたメソッドの中でメンバーの 値を変更すれば、それは直ちに元の変数から参照されている実体のメンバーの値の変更と なります。 しかし、vは同じくsecond()メソッドの中でvalを代入されているではないかと思われるかも しれません。ここで、Javaにおける引数が「値渡し」であることを思い出す必要があります。 呼び出されたメソッドの引数は、あくまで元の参照型変数の「コピー」なのです。参照先を 変更したからといって、元の変数の参照先が変わるわけではありません。ましてや、新しい 参照先のデータが元の参照先に影響を及ぼすものでもありません。 new演算子が使われた時点での実体を思い浮かべ、各変数がそれぞれ何を指し示しているかを 考えれば理解できると思います。

northcurlcurl
質問者

補足

早速の回答ありがとうございます。 Javaにおける引数が「値渡し」とは言えども、main()か ら呼ばれたメソッドにおいて、参照先が変わらない限 り、引数の値を変更し、main()に反映する事が出来ると 考えてよろしいのでしょうか?

関連するQ&A

  • 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
  • JAVAコンストラクタについて

    JAVA のコンストラクタ定義の際に、下記のようにコンストラクタにvoidを付けた時と付けない時の処理結果が変わるのはなぜでしょうか。 (1) class O { protected int d; O(){ System.out.println("O = " + d); } } class Study_6_3main_void { public static void main(String args[]) { int i = 1; O OO = new O(); System.out.println("O = "); } } (2) class O { protected int d; void O(){ System.out.println("O = " + d); } } class Study_6_3main_void { public static void main(String args[]) { int i = 1; O OO = new O(); System.out.println("O = "); } } 実行結果 (1) O = 0 O = (2) O = 以上です。回答の程よろしくおねがいします。

    • ベストアンサー
    • Java
  • java iを1づつ増やすプログラムと2づつ増やすプログラム

    次のようにすればiを1づつ増やして表示されます。 class Calc{   int i=1;   int add(){     return i++;   } } class Count{   public static void main(String[] args){     Calc calc = new Calc();     System.out.println("i = " + calc.add());     System.out.println("i = " + calc.add());     System.out.println("i = " + calc.add());   } } 実行結果 i = 1 i = 2 i = 3 しかし次のように2づつ増やそうとすると、 class Calc{   int i=1;   int add(){     return i+2;   } } class Count{   public static void main(String[] args){     Calc calc = new Calc();     System.out.println("i = " + calc.add());     System.out.println("i = " + calc.add());     System.out.println("i = " + calc.add());   } } 実行結果 i = 3 i = 3 i = 3 このようになってしまいます。どこがおかしいのでしょうか?

    • ベストアンサー
    • Java
  • javaでOXゲーム

    学校で出たjavaの課題に取り組んでいます。 javaでのOXゲームをコマンドプロンプト上で実現したいのですが。どのようなソースコードにすればよいのでしょうか。 皆目検討もつかない状況に陥ってしまいました。 import java.io.*; //盤面クラス class Board{ public void Board(){ int[] board; board = new int[9]; board[0] = 1; board[1] = 2; board[2] = 3; board[3] = 4; board[4] = 5; board[5] = 6; board[6] = 7; board[7] = 8; board[8] = 9; } public void show(){ System.out.println(board[0]+board[1]+board[2]); System.out.println(board[3]+board[4]+board[5]); System.out.println(board[6]+board[7]+board[8]); } } //先攻クラス class First{ } //後攻クラス class Second{ } //判定クラス class Judge{ } //メイン class Game{ public static void main(String[] args)throws IOException { System.out.println("OXゲーム!"); Board b = new Board(); } }

  • javaのプログラムについての質問です。

    /* * 引数、パラメータ、戻り値を使用して * SubTest19クラスでフィールド変数を使用しないよう、 * 修正して下さい。 * * * また、SubTest19クラスのput()で行っている出力はfor文を使用する事。 * */ class Test19 {   public static void main(String[] args) {   // SubTest19クラスのインスタンス化   SubTest19 st19 = new SubTest19();   // setメソッド呼び出し:戻り値&引数無し   st19.set();   // putメソッド呼び出し:戻り値&引数無し   st19.put();   } } // SubTest19クラス class SubTest19 {   public Test19data t19d[] = null;       // setメソッド    public void set(){     t19d = new Test19data[3];     t19d[0] = new Test19data();     t19d[1] = new Test19data();     t19d[2] = new Test19data();     t19d[0].px = "K-0963";     t19d[0].ct = 23;     t19d[1].px = "T-523363";     t19d[1].ct = 517;     t19d[2].px = "J-97553";     t19d[2].ct = 5;   }     // putメソッド   public void put(){      System.out.println(t19d[0].px);     System.out.println(t19d[0].ct);     System.out.println(t19d[1].px);     System.out.println(t19d[1].ct);     System.out.println(t19d[2].px);     System.out.println(t19d[2].ct);   } } class Test19data{   // フィールド変数の宣言:String,int    public String px;    public int ct;    public Test19data(){       px = "";      ct = 0;    } } このような問題なのですが、どうしても出来ずに手詰まり状態です。丸投げで非常に申し訳ないのですが、どなたか途中までコードを書いて頂けないでしょうか?よろしくお願い致します。

  • javaの問題

    import java.util.Scanner; class test6{ static void printArray(int[] a) { for(int i=0;i<a.length;i++) System.out.print(String.format("%1$6s", (a[i]+" "))); System.out.println(); } static void printArray(int[][] a) { for(int[] i:a) { for(int j:i) System.out.print(String.format("%1$6s",(j+"\t"))); System.out.println(); } } public static void main(String[] args) { int[] a = {12,536,-8,7}; int[][] c = {{32,-1,32,45,67}, {535,99999,2}, {2,5,-123,9}}; printArray(a); printArray(c); } } このプログラムを表示するとこのようになるのですが、 12 536 -8 7 32 -1 32 45 67 535 99999 2 2 5 -123 9 これに一工夫加えて見やすくしたいです。 このような形にするのはどのようにすればよいのでしょうか + + | 32 -1 45 67 | | 535 99999 2 | | 2 5 -123 9 | + +

  • javaについて・・・

    このように出力されるプログラムを考えています ↓ 受験者人数を入力してください 3 3人分の点数を入力してください 50 80 20 1人目の点数は50です 2人目の点数は80です 3人目の点数は20です 最高点は80です っという感じのプログラムを考えています。 そしていまここまでプログラムを書いたのはいいのですが 感じんの最高点が表示されません・・・ import java.io.*; class test{ public static void main(String[] args) throws IOException{ System.out.println("テストの受験者数を入力してください。"); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str =br.readLine(); int num = Integer.parseInt(str); int test[] = new int[num]; int max=0; System.out.println(test.length +"人の点数を入力してください"); for(int i=0; i<num; i++){ String str1 = br.readLine(); test[i] = Integer.parseInt(str1); } for(int i=0; j<num; i++){ System.out.println((i+1)+"番目の人の点数は"+ test[i]+"です。"); if(test[i]>max){ max=test[i]; } } System.out.println("最高点は" +max+ "です。"); } } どこをどのように直せば最高点が表示されるようになるでしょうか? ご指摘おねがいします。

  • [javaプログラムについて] うまく動きません。

    import java.*; class Test { void main() { Th th1 = new Th("01スレッド"); Th th2 = new Th("02スレッド"); th1.start(); th2.start(); } } class Th extends Thread { void run(String pri) { for (int i=0;i<5;i++) { System.out.println(pri + " : " + i); } } } スレッドの使い方がいまいちよく分かりません。 どこが間違っているのか教えてください。 宜しくお願い致します。

    • ベストアンサー
    • Java
  • java.lang.NullPointerException

    java初心者です。 ******************************************* Exception in thread "main" java.lang.NullPointerException at Region2.<init>(Region2.java:7) at Region2.main(Region2.java:11) ******************************************* というエラーで困っています。 ソースは、 ******************************************* import java.io.*; public class Region2 {  public Test[] t = new Test[10];  public Region2(){   t[0].x = 1;//ココ   System.out.println(t[0].x);  }  public static void main(String[]args){   Region2 reg = new Region2();//ココ   System.out.println(reg.t[0].x);   System.exit(0);  } } class Test{  public int x;  public Test (int x){//xをセット   this.x = x;  }  public void Show () {//xを表示   System.out.println(x);  } } **************************************** 見ての通りのプログラムで、あまり意味のないものですが、オブジェクトの配列の動作をテストしています。でずが、「ココ」とコメントしたところでたたかれてしまいます。私は恥ずかしながら「え?何でダメなの?」という感じです。 何がいけないのか、もしくはどうすれば、 1 1 と表示されるか、どなたかアドバイスください。

    • ベストアンサー
    • Java
  • Java trimの設定について

    Java trimの設定についてお伺いいたします。 最高気温と最低気温を表示することができずに困っております。trimをどのように設定すれば良いかご教授お願いします。 以下、ソースを記載します。 import java.io.*; public class Sample { public static void main(String[] args) { try{ BufferedReader br = new BufferedReader(new FileReader("kion.txt")); System.out.println("気温データ出力"); int test[] = new int[4]; String str; for(int i=0;i<test.length;i++){ str = br.readLine(); } int max = 0; int min = 0; for(int i=0;i<test.length;i++){ if(max < test[i]) max = test[i]; if(min > test[i]) min = test[i]; System.out.println(test[i]); } System.out.println("最高気温" + max + "です。"); System.out.println("最低気温" + min + "です。"); br.close(); } catch(IOException e){ System.out.println("入出力エラーです"); } } } また「kion.txt]は 東京 30.2 18.5 神奈川 34.2 18.5 埼玉 29.8 16.4 千葉 27.5 14.7 と作成しました。 これを 最高気温 神奈川 34.2 最低気温 千葉  14.7 と表示したいのですが、現在は「0 0 0 0」と表示するだけです。 何卒、よろしくお願い致します。

専門家に質問してみよう