如何在 Java 中对基元执行通过引用传递的等效操作

2022-08-31 08:41:30

此 Java 代码:

public class XYZ {   
    public static void main(){  
        int toyNumber = 5;   
        XYZ temp = new XYZ();  
        temp.play(toyNumber);  
        System.out.println("Toy number in main " + toyNumber);  
    }

    void play(int toyNumber){  
        System.out.println("Toy number in play " + toyNumber);   
        toyNumber++;  
        System.out.println("Toy number in play after increement " + toyNumber);   
    }   
}  

将输出以下内容:

 
Toy number in play 5  
Toy number in play after increement 6  
Toy number in main 5  

在C++我可以将变量作为传递引用传递,以避免阴影,即创建同一变量的副本,如下所示:toyNumber

void main(){  
    int toyNumber = 5;  
    play(toyNumber);  
    cout << "Toy number in main " << toyNumber << endl;  
}

void play(int &toyNumber){  
    cout << "Toy number in play " << toyNumber << endl;   
    toyNumber++;  
    cout << "Toy number in play after increement " << toyNumber << endl;   
} 

C++输出将是这样的:

Toy number in play 5  
Toy number in play after increement 6  
Toy number in main 6  

我的问题是 - Java中的等效代码是什么,以获得与C++代码相同的输出,因为Java是按值传递而不是通过引用传递的


答案 1

您有多种选择。最有意义的一个实际上取决于你想做什么。

选项 1:使 toyNumber 成为类中的公共成员变量

class MyToy {
  public int toyNumber;
}

然后将对 MyToy 的引用传递给您的方法。

void play(MyToy toy){  
    System.out.println("Toy number in play " + toy.toyNumber);   
    toy.toyNumber++;  
    System.out.println("Toy number in play after increement " + toy.toyNumber);   
}

选项 2:返回值而不是通过引用传递

int play(int toyNumber){  
    System.out.println("Toy number in play " + toyNumber);   
    toyNumber++;  
    System.out.println("Toy number in play after increement " + toyNumber);   
    return toyNumber
}

此选择需要对 main 中的 callite 稍作更改,使其显示为 。toyNumber = temp.play(toyNumber);

选项 3:使其成为类或静态变量

如果这两个函数是同一类或类实例上的方法,则可以将 toyNumber 转换为类成员变量。

选项 4:创建 int 类型的单元素数组并传递

这被认为是一种黑客攻击,但有时用于从内联类调用返回值。

void play(int [] toyNumber){  
    System.out.println("Toy number in play " + toyNumber[0]);   
    toyNumber[0]++;  
    System.out.println("Toy number in play after increement " + toyNumber[0]);   
}

答案 2

Java不是通过引用调用的,它只是按值调用的

但对象类型的所有变量实际上都是指针。

因此,如果您使用可变对象,您将看到所需的行为

public class XYZ {

    public static void main(String[] arg) {
        StringBuilder toyNumber = new StringBuilder("5");
        play(toyNumber);
        System.out.println("Toy number in main " + toyNumber);
    }

    private static void play(StringBuilder toyNumber) {
        System.out.println("Toy number in play " + toyNumber);
        toyNumber.append(" + 1");
        System.out.println("Toy number in play after increement " + toyNumber);
    }
}

此代码的输出:

run:
Toy number in play 5
Toy number in play after increement 5 + 1
Toy number in main 5 + 1
BUILD SUCCESSFUL (total time: 0 seconds)

您也可以在标准库中看到此行为。例如 Collections.sort();Collections.shuffle();这些方法不返回新列表,但修改其参数对象。

    List<Integer> mutableList = new ArrayList<Integer>();

    mutableList.add(1);
    mutableList.add(2);
    mutableList.add(3);
    mutableList.add(4);
    mutableList.add(5);

    System.out.println(mutableList);

    Collections.shuffle(mutableList);

    System.out.println(mutableList);

    Collections.sort(mutableList);

    System.out.println(mutableList);

此代码的输出:

run:
[1, 2, 3, 4, 5]
[3, 4, 1, 5, 2]
[1, 2, 3, 4, 5]
BUILD SUCCESSFUL (total time: 0 seconds)