簡體   English   中英

Java參數傳遞問題

[英]Java parameter passing question

我對Java比較陌生,在嘗試使用某些代碼時遇到了令我驚訝的事情。 希望有人能夠對此有所了解。 這是與我的問題相關的一些代碼片段。 那些閱讀過編程實踐的人可能會覺得這很熟悉。

此函數是為List數據類型定義的,並將傳遞的“fn”參數(只是包裝在對象中的函數)應用於列表的所有成員。

    public void apply(MapFunctionI fn, Object fnArg) {
    Node curr = head;
    for (; curr != null; curr = curr.getNext()){
        fn.function(curr.getItem(), fnArg);
    }
}

接下來,我嘗試使用這個函數來計算列表中元素的數量,使用實現MapFunctionI的類(一個需要一個名為'function'的方法的接口)

class CounterFunction implements MapFunctionI {
public void function(Object node, Object arg){
    ((MyInteger)arg).increment();
}
}

這是我怎么稱呼這個。

    static void TestApply(LinkedList l){
    System.out.println("Number of elements in List -> ");
    MyInteger n = new MyInteger(0);
    l.apply(new CounterFunction(),n);
    System.out.println(n.value());
}

這是MyInteger類型。

class MyInteger {
private int n;

MyInteger(int i){
    n = i;
}

public void increment(){
    n++;
}

public int value(){
    return n;
}

現在,如果您想知道我為什么使用自己的Integer類型,那就是我的問題。 我嘗試使用Java Integer類型,但我無法使其工作,打印的答案始終為O,“整數”的值不會在多個調用中持續存在。 我是這樣做的,

arg = ((Integer)arg).intValue() + 1;

什么解釋了這種行為?

我相信有一個更簡潔的方式來提出這個問題:-)

第一個問題是類型Integer是不可變的; 一旦使用某個整數值創建,該值就無法更改。 所以你不能直接改變一個整數(我不是說你不知道這個或試過)。

下一個問題是傳遞給函數的是對該Integer的引用。 您可以在函數內部將該引用更改為指向不同值的Integer,但是函數內部更改的引用永遠不會傳遞回調用函數,因此其值與此無關。

您的自制類的工作原因是您現在正在更改對象的內部內容而不僅僅是對它的引用。 函數內部和外部都存在相同的對象,因此當您在內部更改它時,確實可以在外部看到更改。

使用Integer類型時它不起作用的原因是因為您正在更新function()中的arg指針的本地副本。 在Java中,所有非基元都是“引用類型”,所有函數參數都是按值傳遞的。

編輯 - 如果最后一個語句令人困惑,想象一下你是否正在使用C ++方言,它只允許你按值傳遞引用(即你只能傳遞指針的副本),並且你想要實現swap函數。 不可能,對吧? 更新本地指針不會影響傳遞給函數的指針。

首先,Java的Integer類是不可變的; 它只代表一個整數值。 當你在它上面調用intValue() ,它只是返回整數的當前(不可變)值。

當你將(未裝箱和重新裝箱的)增量值分配給argarg只是對傳入內容的本地引用(就像C中函數內的指針值一樣)。 設置為某個東西然后從該函數返回會丟失您剛給它的新值。

如果您使用的是C / C ++,那么您可以使用指向指針的指針。 但是Java沒有相應的構造,所以你自己處理它 - 你使用的包裝器對象是你問題的合理解決方案。

發生這種情況是因為在Java中,參數傳遞是BY VALUE。 請注意,當您將對象傳遞給函數時,您將傳遞BY VALUE其引用...或者,以另一種方式說,您按值傳遞其地址。

當你寫:

arg = .... // a new Integer Object

你在函數中本地更改arg引用的值(指向新對象),而保存在List.apply函數中的fnArg變量中的引用仍然是相同的(因此指向相同的整數(0) )。

如果您了解C ++,那么您在具有int *或int *&作為參數的函數中具有相同的區別:在Java中,它就像擁有int *(對於對象)。

最后一個代碼部分的問題是arg變量只保存對Integer類的引用。 當您將arg設置為某個值時,其值將在本地上下文中替換為新對象,並且不會更新已存在的對象。 您必須指定要更新的引用的完整路徑。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM