将Class中对象的地址复制到参数中,以便稍后对该对象进行更改

时间:2012-04-26 17:44:14

标签: java

在我的原始代码中,我正在向树中添加节点。我的目标是以某种方式访问​​我在树中添加的最后一个节点(我的想法是创建另一个指向最后一个对象的对象(我原始示例中的节点))。

public class RandomSubClass 
{
    int firstNum;
}    

import java.util.LinkedList;

public class RandomClass 
{
    LinkedList<RandomSubClass> myListOfObjects = new LinkedList<RandomSubClass>();

    void addItem(int firstNum, RandomSubClass toBeReturned)
    {       
        RandomSubClass o1 = new RandomSubClass();
        o1.firstNum = firstNum;
        myListOfObjects.add(o1);

        // Here I was thinking that 'toBeReturned' will get same address as
        // 'o1', and by changing 'toBeReturned' (in main), values in 'o1' change
        //
        toBeReturned = o1;

        // This following commented code worked, 
        // but I can't use it in my original code.
        //
        // The reason I can't use it is because when I add a node to a tree, 
        // I start at the root and trace the new node's way to a new leaf, 
        // which makes it hard to do (simply) that.
        //
        //toBeReturned.firstNum = firstNum;
        //myListOfObjects.add(toBeReturned);
    }   
}

public class Main 
{
    public static void main(String[] args) 
    {
        RandomClass myList = new RandomClass();

        RandomSubClass r1 = new RandomSubClass();
        RandomSubClass r2 = new RandomSubClass();

        myList.addItem(1, r1);
        myList.addItem(2, r2);

        // I would like to do that, and see changes in the node in 'myList'
        //  
        r1.firstNum = 10;
        r2.firstNum = 20;
    }
}

我想在将节点添加到树后检查节点,如果它满足某些条件,我想更改该节点的标志。

我可以再次重新跟踪节点(从root开始),但是我的树在某些时候可能变得很大并且需要时间。因此,如果我在添加它时获取该节点的地址,并且在检查了我的条件之后,我可以修改该地址的标志,知道它将更改该节点上的标志(最后添加)。

3 个答案:

答案 0 :(得分:2)

是的,你可以这样做。我允许你:-)但是你的示例代码不起作用,因为Java对象是按值传递的,而不是通过引用传递的。也就是说,当您将对象传递给函数时,如果重新分配该对象,则它对调用者没有影响。例如:

void caller()
{
  String s1="Hello";
  updateString(s1);
  System.out.println(s1);
}
void updateString(String s1)
{
  s1="Goodbye";
}

此功能的输出为“Hello”,而不是“Goodbye”。 updateString函数中的赋值不会更改调用者传入的值。

有(至少)三种方法可以做你想做的事。

方法1:最简单的方法是返回新对象,而不是更新参数:

SomeObject addItem(int firstnum)
{
  SomeObject o1=new SomeObject();
  o1.firstnum=firstnum;
  objectList.add(o1);
  return o1;
}
...
void callingFunction()
{
  SomeObject newObject=addItem(1);
  newObject.secondnum=2;
  ... etc ...
}

我更喜欢这种方法,我不需要其他一些返回值:它干净简单。

方法2:创建一个全局变量并在那里存储对象的句柄。但是这种方法很糟糕,因为全局变量很糟糕。我只提到它告诉你不要这样做。

方法3:创建一个包装器来保存对象的引用。然后将包装器传递给“add”函数,该函数可以更新类中的值。

class SomeObjectWrapper
{
  public SomeObject someObject;
}
...
void addItem(int firstnum, SomeObjectWrapper sow)
{
  SomeObject o1=new SomeObject();
  o1.firstnum=firstnum;
  objectList.add(o1);
  sow.someobject=o1;
}
...
void callingFunction()
{
  SomeObjectWrapper sow=new SomeObjectWrapper();
  SomeObject newObject=addItem(1, sow);
  sow.someObject.secondnum=2;
  ... whatever ...
}

答案 1 :(得分:1)

如何使用返回值执行此操作:

RandomSubClass addItem(int firstNum)
{       
    RandomSubClass o1 = new RandomSubClass();
    o1.firstNum = firstNum;
    myListOfObjects.add(o1);

    // Here I was thinking that 'toBeReturned' will get same address as
    // 'o1', and by changing 'toBeReturned' (in main), values in 'o1' change
    //
    ....
    return o1
}

答案 2 :(得分:0)

在Java中,所有对象都通过地址返回/传递。如果希望通过地址使用传递基元类型,则只传递基元类型(int,float,double ...)的值: -Integer而不是int - 双倍而不是双倍 -Float而不是Float -ect ...