-1

これがどのように機能するのか理解できません

public void addToRule(Rule r) {
    if (!getRuleList().contains(r)) {
        getRuleList().addElement(r);
    }
}

このコードを実行すると:

obj.addToRule(r);
System.out.println(getRuleList().contains(r));

どのようにこれが起こるtrueことができますか?

ところで、ruleList はメイン クラスのベクトル メンバーであり、静的変数ではありません (これは問題ではないと思いますが、とにかく共有します)。

import java.util.Vector;


public class RuleEngine{

    private Vector ruleList = new Vector();

    public Vector getRuleList(){
        return ruleList;
    }

    public void addToRule(Rule r){
        if(!getRuleList().contains(r))
            getRuleList().addElement(r);
    }

    public static void main(String args[]){
        RuleEngine re = new RuleEngine();
        Rule r = new Rule("Rule1");
        re.addToRule(r);
        System.out.println(re.getRuleList().contains(r));
    }
}

class Rule{
    public String name = "";
    public Rule(String nam){
        this.name=nam;
    }
}

OK の人々は、Java での参照による受け渡しのためにこれが機能すると私に言いました。わかった。しかし、参照ではなくそのオブジェクトのコピーを取得するにはどうすればよいでしょうか?

4

4 に答える 4

1

リスト(または同様のもの)への参照getRuleList()を返していると思います。Cに精通している場合は、これをポインター(またはより具体的にはポインターのコピー)と考えてください。を呼び出すと、オブジェクトの同じ基になるインスタンスで作業していることになります。getRuleList()

証明のために、試してみてください:System.out.println(getRuleList() == getRuleList()); 演算子は==、2つの参照が同じオブジェクトを指している場合にのみ比較します(のような深い等式ではありません.equals)。setRuleList()別のオブジェクト参照を使用して呼び出すまで、ステートメントが当てはまることがわかります。

もちろん、これらの仮定は、完全なコードを見ることなく行われます。

于 2011-09-02T11:53:30.447 に答える
1

したがって、質問に答えるには、まず Java が変数を渡す方法を知る必要があります。

変数には次の値があります。

int i = 1234;
Person p = new Person("Peter");

ここで、変数 i には正確に 1234 が含まれ、変数 p には作成された人物のメモリ アドレスが含まれます。

つまり、i には 1234 が含まれ、p にはアドレス (a4dfi3 としましょう) が含まれます。

anyMethodYouLike(p);
System.out.println(p.getName());
public void anyMethodYouLike(Person somePerson) {
   somePerson.rename("Homer");
}

したがって、この例では、メソッド anyMethodYouLike に変数 p を指定します... 待ってください! メソッドに変数の値 (a4dfi3) を指定します。メソッドは次に、この変数の rename を呼び出します (これは p と同じアドレスを持っているため、p が指すのと同じ Person を変更します)。そのため、メソッドの後に p が指している人物の名前が出力され、結果として「ホーマー」になります。

someOtherMethod(p);
System.out.println(p.getName());
public void someOtherMethod(Person somePerson) {
   somePerson = new Person("Walter");
}

この例では、"Peter" という Person のアドレスを Method に渡します。しかし今回は、メソッドは somePerson に新しい Person を作成します (したがって、somePerson のアドレスを 13n37s にオーバーライドします。しかし、a4dfi3 の Person は変更されていません! print 呼び出しは、「Walter」ではなく「Peter」を出力します。 .

それでは、これがプリミティブでどのように動作するかを見てみましょう。

someMethod(i);
System.out.println(i);
public void someMethod(int someInt) {
   someInt++;
}

したがって、i の値 (1234) が someInteger に渡されます。その後、someInteger は 1235 にインクリメントされます。しかし、i はまだ 1234 です。

これが Java のオブジェクトとプリミティブの大きな違いです。

お役に立てれば幸いです、Ferdi265

于 2013-02-24T10:46:35.877 に答える
0

あなたのコメントから、Java の値と参照の違いを完全には理解していないようです。基本的に、Java ではオブジェクトは常に参照として渡されます。

検討

class Test {
    private List list = new ArrayList();
    public List getList() {
        return list;
    }
}

このgetList()メソッドは、オブジェクトへの参照listを返します。オブジェクトのコピーは返されません。listのようなことをする

Test test = new Test();
String s = "ABC";
test.getList().add(s);
System.out.println(test.getList().contains(s));

getList()最初に呼び出されてから trueを返し、リストへの参照が返され、その上でadd(s)呼び出されます。2 回目getList()に呼び出されると、同じリストへの参照が返されます。そのコピーではなく、新しいリストではなく、同じ参照が返されます。contains(s)オブジェクトsが追加されたのと同じリストであるため、呼び出すと true が返されます。

ただし、これを考慮してください。

Test test1 = new Test();
Test test2 = new Test();
String s = "ABC";
test1.add(s);
System.out.println(test2.getList().contains(s));

これにより、「false」が出力されます。なんで?test1test1.getList()内のリストへの参照を返し、 test2内のリストへの参照を返します。ここでは、test1:s リストに追加されたため、test2:s リストには含まれません。test2.getList()s

于 2011-09-02T12:05:34.617 に答える
0

trueルールが存在しない場合に備えてルールをルール リストに追加するため、常に が出力されます。何が起こるか:

  • オブジェクトにルールを追加するように指示する ルール リストにルールを追加する
  • オブジェクトはルールが存在するかどうかを確認し、存在しない場合は追加します

そのため、コードの実行後にルールが含まれていることが保証されます。

于 2011-09-02T11:43:24.170 に答える