繁体   English   中英

如何在Java中将对象的引用作为参数返回

[英]How to return reference to object as parameter in Java

虽然我已经编写了C,C ++和C#多年,但我只是表面上熟悉Java。 通过Java学院项目帮助我的Comp Sci子,他需要从Java中的方法返回对两个对象的引用。 我建议将一个作为函数值返回,将第二个作为参考。 他不知道该怎么做。 我做了一点研究,意识到这可能是不可能的。 我的问题是在Java中,当一个方法需要返回一个对象的多个引用时,常用的方法是什么。 这是我儿子案例中的具体例子。

// This method returns references to the head and tail objects from the passed in 
// linked list.  The head object is returned as the function value and the tail is 
// returned as a parameter.
public Static Node GetHeadTail(List list, Node tail)

我意识到上面的代码在Java中不起作用,因为tail是对节点的引用,而在Java中引用本身是通过值传递的。 在Java中处理这个问题最常见的方法是什么? 我儿子的解决方案是为函数值返回一个2节点对象的数组。 我说这是一个糟糕的解决方案,因为它没有记录数组中每个元素的含义。 另一种解决方案是创建一个包含头部和尾部引用的对象。 然而,在特定示例中,头指针是最感兴趣的,并且如果返回对象,则如果他们想要的只是头部,则会为该方法的调用者创建不期望的编码开销。

在这种情况下,java程序员通常会创建一个包含2个成员的类: headtail 这将是getHeadTail(List list)方法的返回类型。

您只能通过Java传递值。 你最好的解决方案是你儿子建议的第二个解决方案,即返回一个有头部和尾部的物体。

Java始终是按值传递的。 困难的是可以理解Java将对象作为引用传递,并且这些引用是按值传递的。 Java是“通过引用传递”还是“按值传递”?

但是,你有能力做这样的事情:

public static void main(String[] args)
{
    Car c = new Car("Blue");
    System.out.println(c.getName());
    changer(c);
    System.out.println(c.getName());
}

public static void changer(Car c)
{
    c.setName("Red");
}

汽车课。

public class Car 
{
    private String name;

    public Car(String n)
    {
        name = n;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String n)
    {
        name = n;
    }
}

输出将是:

Blue
Red

知道了这一点,你就可以改变tail指向的东西,并且仍然能够返回head

Java做了这个有趣的事情,它是传递值和传递引用之间的混合体。 基本上,函数不能更改参数,但函数可以通过调用其中的某个方法来请求参数更改自身。 这个答案很好地解释了它。

回应“在Java中处理这个问题的最常见方式是什么?” 你创建一个包含头尾参考的类的解决方案可能是最常见和最好的做法。 如果可能的话,最好只有单独的getHead和getTail方法。

一个稍微不那么明显的解决方案:使用其中一个内置类型,如Queue或LinkedList,它们已经有头尾。

LinkedList list = new LinkedList();
head = list.getFirst();
tail = list.getLast();

根据您的需要,有很多这样的类型。 阅读文档。

一种有点hacky技术是使用数组作为参数。 然后,该函数可以更改一个或多个元素的值以“返回”它。 它并不漂亮,但可以完成工作,并且无需为此目的创建特殊的包装器对象。

正如旁注,Scala通过让你返回元组来解决这个问题。

如果您尝试实现一个返回多个值作为参数的方法,您可以使用以下内容:

public class Future<T> {
  private T instance;

  public T get() {
    return this.instance;
  }

  public void set(T value) {
    this.instance = value;
  }
}

并像这样使用它:

class MyCrazyClass {

  private static void myCrazyMethod(Future<String> returnVal1, Future<Integer> returnVal2, Future<Float> returnVal3) {
    returnVal1.set("We are cool!");
    returnVal2.set(123);
    returnVal3.set(321F);
  }

  public static void main(String[] args) {
    Future<String> strRetVal = new Future<>();
    Future<Integer> intRetVal = new Future<>();
    Future<Float> floatRetVal = new Future<>();

    myCrazyMethod(strRetVal, intRetVal, floatRetVal);

    System.out.println(strRetVal.get());
    System.out.println(intRetVal.get());
    System.out.println(floatRetVal.get());
  }
}

输出:

We are cool!
123
321.0

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM