簡體   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