开发者

Java Object Reference and Java Methods

I am unable to understand how this works

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

If I run this code:

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

it prints out true how can this happen?

btw ruleList is a vector member of the main class and is not a static variable(don't think this matters but sharing anyway).

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 people have told me that this works beca开发者_JS百科use of the pass by reference in java. I get it. but what can i do to get a copy of that object instead of its reference?


I'm guessing getRuleList() is returning a reference to a List (or something similar). Think of it as a pointer (or more specifically, a copy of a pointer) if you're familiar with C. You're working on the same underlying instance of the object when you call getRuleList().

For proof, try: System.out.println(getRuleList() == getRuleList()); The == operator will only compare if the two references are pointing to the same object (not a deep equal like .equals). You'll see that until you call setRuleList() with a different object reference that the statement holds true.

These assumptions are of course without seeing your full code.


So, to answer your questions you have to at first know how Java passes Variables.

a Variable has a value:

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

Now, the Variable i contains exactly 1234, while the Variable p contains the Memory Adress of the created Person.

so i contains 1234 and p contains the adress (let's say a4dfi3).

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

so in this example, we give the Method anyMethodYouLike the Variable p... wait! we give the Method the value of the Variable (a4dfi3). The Method then calls rename on this Variable (which still has the same adress as p has, hence it modifies the same Person that p points to). So, after the Method, the Name of the Person p points to, gets printed, which results in "Homer".

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

In THIS example we still give the adress of our Person called "Peter" to the Method. But this time, the Method creates a new Person in somePerson (therefore overriding the adress in somePerson to.. let's say 13n37s. BUT! the Person at a4dfi3 wasn't changed! The print call still outputs "Peter" and not "Walter".

Now, let's see how this behaves with primitives:

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

So, the Value of i (1234) gets passed to someInteger. Then someInteger gets incremented to 1235. But i is still 1234.

This is the big difference between Objects and primitives in Java.

Hope I could help, Ferdi265


From your comments it looks like you have not completely understood what the difference is between a value and a reference in Java. Basically, objects are always passed around as references in Java.

Consider

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

The getList() method will return a reference to the list object. It will not return a copy of the list object. Doing something like

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

Will return true since the first time getList() is called, a referece to the list is returned, on which add(s) is invoked. The second time getList() is called, it returns a reference to the same list, not a copy of it, not a new list - the same reference. Calling contains(s) will return true since it the same list onto which the object s was added.

Consider this, however.

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

This will print out "false". Why? test1.getList() returns a reference to the list inside test1 and test2.getList() returns a reference to the list inside test2. Here, s was added to test1:s list, so it will not be contained inside test2:s list.


It should always print true, because you add the rule to the rule list in case it is not there. What happens is:

  • you tell the object to add add a rule to its rule list
  • the objects checks if the rule exists, and if it doesn't, adds it

So it is guaranteed to contain the rule after the code is executed.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜