在Java中如何做相当于基元传递的参考

这个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); } } 

会输出这个:

 
玩具中的数字5  
发牌后的玩具号码6  
玩具编号在主要5  

在C ++中,我可以通过引用传递toyNumbervariables来避免阴影,即创build一个相同variables的副本,如下所示:

 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 ++的输出将是这样的:

玩具中的数字5  
发牌后的玩具号码6  
玩具编号在主要6  

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

你有几个select。 最有意义的取决于你想要做什么。

select1:使玩具成为class级中的公共成员variables

 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); } 

select2:返回值而不是通过引用

 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 } 

这个select将需要对主要的callsite进行一个小的改变,以便读取: toyNumber = temp.play(toyNumber);

select3:使其成为一个类或静态variables

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

select4:创build一个types为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]); } 

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

但是,对象types的所有variables实际上都是指针。

所以,如果你使用一个可变的对象,你会看到你想要的行为

 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) 

做一个

 class PassMeByRef { public int theValue; } 

然后传递一个对它的实例的引用。 请注意,最好避免通过参数来改变状态的方法,特别是在并行代码中。

在Java中,您不能通过引用传递基元。 对象types的所有variables当然都是指针,但我们称之为“引用”,它们也总是按值传递。

在真的需要传递一个基元的情况下,有时候人们会做的是将这个参数声明为基本types的数组,然后传递一个单元数组作为参数。 所以你传递一个引用int [1],在这个方法中,你可以改变数组的内容。

对于一个快速的解决scheme,你可以使用AtomicInteger或任何primefacesvariables,这些variables可以让你使用内置的方法改变方法内部的值。 这里是示例代码:

 import java.util.concurrent.atomic.AtomicInteger; public class PrimitivePassByReferenceSample { /** * @param args */ public static void main(String[] args) { AtomicInteger myNumber = new AtomicInteger(0); System.out.println("MyNumber before method Call:" + myNumber.get()); PrimitivePassByReferenceSample temp = new PrimitivePassByReferenceSample() ; temp.changeMyNumber(myNumber); System.out.println("MyNumber After method Call:" + myNumber.get()); } void changeMyNumber(AtomicInteger myNumber) { myNumber.getAndSet(100); } } 

输出:

 MyNumber before method Call:0 MyNumber After method Call:100 
 public static void main(String[] args) { int[] toyNumber = new int[] {5}; NewClass temp = new NewClass(); temp.play(toyNumber); System.out.println("Toy number in main " + toyNumber[0]); } 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]); }