2015-09-11 8 views
5

Javaは、値渡し(常にコピーで動作します)をサポートしますが、ユーザー定義オブジェクトを渡すと、実際のオブジェクト(参照渡しの種類はポインタの変更の種類)なぜchangeObject2CLEARメソッドが実際にオブジェクトの値を変更しているのか理解していますか?代わりにそれはコピーで動作する必要がありますか?Javaでの値渡しの問題


import java.util.HashMap; 
import java.util.Map; 

public class PassBy { 

    class CustomBean { 
     public CustomBean() { 

     } 

     private int id; 
     private String name; 

     public int getId() { 
      return id; 
     } 
     public void setId(int id) { 
      this.id = id; 
     } 
     public String getName() { 
      return name; 
     } 
     public void setName(String name) { 
      this.name = name; 
     } 

     @Override 
     public String toString() { 
      return id + ", " + name; 
     } 
    } 

    public Map<Integer, String> changeObject2NULL (Map<Integer, String> m) { 
     m = null; 
     return m; 
    } 

    public Map<Integer, String> changeObject2CLEAR (Map<Integer, String> m) { 
     m.clear(); 
     return m; 
    } 

    public CustomBean changeCustomObject (CustomBean _e) { 

     _e.setId(_e.getId() + 1); 
     return _e; 
    } 

    public static void main(String[] args) { 

    PassBy passby = new PassBy(); 

    Map<Integer, String> map = new HashMap<Integer, String>(); 
    map.put(1, "value"); 

    CustomBean bean = passby.new CustomBean(); 
    bean.setId(1); 
    bean.setName("arun"); 

    // Initial Value 
    System.out.println(map.toString()); 
    System.out.println(bean.toString()); 
    System.out.println("-------------------------"); 

    // Pass by value works fine 
    passby.changeObject2NULL(map); 
    passby.changeCustomObject(bean); 

    // Custom object value changes since we pass as the object reference but Map remains with actual value 
    System.out.println(map.toString()); 
    System.out.println(bean.toString()); 
    System.out.println("-------------------------"); 

    // Testing Pass by value - CANT UNDERSTAND why it changed the object since it has to be pass-by-value and not by ref in this case ?? 
    // Why setting to null not chainging the value but clear does ? 
    passby.changeObject2CLEAR(map); 
    System.out.println(map.toString()); 

    } 
} 
+0

*参照*を値渡ししています。 Googleについてこれについてたくさん説明します。良い質問。 – Bathsheba

+1

@Arunあなたの質問の洗練されたフォームに対処するために自分の答えを更新しました –

+0

短く 'changeObject2NULL(Map m)はメソッドパラメータである独自のローカル変数* mを含みます。 'changeObject2NULL(map)'のようにこのメソッドを使うと、 'm'は' map'が保持しているオブジェクトに関する情報をコピーします(このアドレスは 'map'変数の* value *です)。したがって、 'm.clear()'を呼び出すと 'map'が保持する同じオブジェクトに対して' clear'メソッドが呼び出されるので、 'map'を介してそのオブジェクトの新しい状態を見ることができます。'm = null'を呼び出すと、単に' m'が 'null'に保持するオブジェクトを変更するだけです。これは 'map'やそれが参照しているオブジェクトには影響しません。 – Pshemo

答えて

1

あなたはインスタンスmapを渡しているchangeObject2CLEAR

passby.changeObject2CLEAR(map); 

を呼び出します。

方法で

changeObject2CLEAR

public Map<Integer, String> changeObject2CLEAR (Map<Integer, String> m) { 
    m.clear(); 
    return m; 
} 

あなたはこの方法でそれがmと呼ばれていても、同じインスタンスmap.clear()を行います。

理解の練習として、次の方法が同じことを行うことに注意してください。

public void changeObject2CLEAR (Map<Integer, String> m) { 
    m.clear(); 
} 

あなたがアクセス権を持っているmapは、メソッドが呼び出された場所に渡された同じインスタンスオブジェクトであるので、あなたがMap<Integer, String> mを返却する必要がないことに注意してください。

編集:なぜm = null;は値渡しとして動作しますが、m.clear()は参照渡しとして動作しますか?

を使用する場合には値nullもしnull新しいメモリ位置への以前のインスタンスオブジェクトmapからの参照を変更するm「へ割り当てます」。あなたは結果的に、あなたがmapオブジェクトを変更、mapによって参照されるメモリロケーションにある同じオブジェクトのメソッドを呼び出しているインスタンスオブジェクトm.clear()メソッドを呼び出す

0

私の知る限り、Javaは唯一の値でパスを行いますが、値が実際に

+0

これは 'Object'インスタンスに当てはまりますが、プリミティブ型ではありません –

+0

なぜオブジェクトをnullに設定するのが値渡しですが、クリアメソッドがpass-by-refですか? – AKS

+0

'null'なのでを基準とし、nullを割り当てることによって、あなたは、それによってしばらく明確に変更し、その参照は、関数へ – miau

3

を参照しているので、Javaは常に値によって渡さん、私はあなたが理解しやすくしてみましょうが、私はあなたが知っている確信していますすべてのオブジェクトインスタンスが実際にそれらのオブジェクトへのポインタであることを示します。これでオブジェクトを送信すると、そのオブジェクトのアドレスの値が渡されます。オブジェクト自体(m.clear()など)に変更を加えた場合は、そのアドレスに移動し、オブジェクトをキャストして操作を実行します。しかし、m = nullのようにポインタ自体を変更すると、保持しているアドレスのコピーだけが変更されます。

+2

downvoterを渡されたオブジェクトを作業していたオブジェクトを「負け」、現在のスコープ内の参照を変更しているので、コメントする気に?これは正解です。少なくとも、間違った答えではありません。 –

+0

質問は重複しているので、私はこの質問と重複の両方のすべての回答に投票しています。複製物の回答はこれよりはるかに優れています。だから、IMO、それは何も役に立つものを追加しません。追加するものがある場合は、その回答を複製に追加します。 – Bathsheba

+1

@Bathshebaもちろん、あなたが好きなように自由にダウンボートすることができますが、質問が積極的に間違っているか有害であるときには、ダウンボートするのが良い方法です。それがちょうど別の答えほど良くなければ、私はより良い答えをアップアップし、あまり良い答えをそのままにしておきます。言い換えれば、私はより良い答えが上に上がるのを助け、あまり良い答えを沈めさせることを心配しないでください。 – yshavit