如何在 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);
}
}
将输出以下内容:
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
My问题是 - Java 中获得与 C++ 代码相同的输出的等效代码是什么,考虑到 Java是按值传递而不是通过引用传递?
This Java code:
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);
}
}
will output this:
Toy number in play 5 Toy number in play after increement 6 Toy number in main 5
In C++ I can pass the toyNumber
variable as pass by reference to avoid shadowing i.e. creating a copy of the same variable as below:
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;
}
and the C++ output will be this:
Toy number in play 5 Toy number in play after increement 6 Toy number in main 6
My question is - What's the equivalent code in Java to get the same output as the C++ code, given that Java is pass by value rather than pass by reference?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
你有几种选择。最有意义的实际上取决于您想要做什么。
选择 1:使 toyNumber 成为类中的公共成员变量
,然后将对 MyToy 的引用传递给您的方法。
选择 2:返回值而不是通过引用传递
此选择需要对 main 中的调用点进行一些小更改,以便其读取:
toyNumber = temp.play(toyNumber);
。选择3:将其设为类或静态变量
如果这两个函数是同一类或类实例上的方法,则可以将 toyNumber 转换为类成员变量。
选择 4:创建 int 类型的单元素数组并传递该数组
这被认为是一种 hack,但有时用于从内联类调用返回值。
You have several choices. The one that makes the most sense really depends on what you're trying to do.
Choice 1: make toyNumber a public member variable in a class
then pass a reference to a MyToy to your method.
Choice 2: return the value instead of pass by reference
This choice would require a small change to the callsite in main so that it reads,
toyNumber = temp.play(toyNumber);
.Choice 3: make it a class or static variable
If the two functions are methods on the same class or class instance, you could convert toyNumber into a class member variable.
Choice 4: Create a single element array of type int and pass that
This is considered a hack, but is sometimes employed to return values from inline class invocations.
Java 不是按引用调用,而是仅按值调用,
但所有对象类型的变量实际上都是指针。
因此,如果您使用可变对象,您将看到您想要的行为
代码输出:
您也可以在标准库中看到此行为。
例如 Collections.sort(); Collections.shuffle();
这些方法不会返回新列表,而是修改其参数对象。
该代码的输出:
Java is not call by reference it is call by value only
But all variables of object type are actually pointers.
So if you use a Mutable Object you will see the behavior you want
Output of this code:
You can see this behavior in Standard libraries too.
For example Collections.sort(); Collections.shuffle();
These methods does not return a new list but modifies it's argument object.
Output of this code:
创建 a
然后传递对其实例的引用。请注意,最好避免使用通过其参数改变状态的方法,尤其是在并行代码中。
Make a
then pass a reference to an instance of it. Note that a method that mutates state through its arguments is best avoided, especially in parallel code.
为了快速解决方案,您可以使用 AtomicInteger 或任何原子变量,这将允许您使用内置方法更改方法内的值。这是示例代码:
输出:
For a quick solution, you can use AtomicInteger or any of the atomic variables which will let you change the value inside the method using the inbuilt methods. Here is sample code:
Output:
在 Java 中不能通过引用传递基元。当然,所有对象类型的变量实际上都是指针,但我们称它们为“引用”,并且它们也总是按值传递。
在确实需要通过引用传递基元的情况下,人们有时会做的是将参数声明为基元类型的数组,然后传递单元素数组作为参数。因此,您传递一个引用 int[1],并且在该方法中,您可以更改数组的内容。
You cannot pass primitives by reference in Java. All variables of object type are actually pointers, of course, but we call them "references", and they are also always passed by value.
In a situation where you really need to pass a primitive by reference, what people will do sometimes is declare the parameter as an array of primitive type, and then pass a single-element array as the argument. So you pass a reference int[1], and in the method, you can change the contents of the array.
“Pass-by...”在Java 和C 中保留。除此之外,如果您打算更改作为引用给出的原语的包装器实例,则可以通过反射来完成。
整数
示例。输出为 6,如 C++ 示例中所示。反射是必需的,因为 Java 设计认为原始包装器是不可变的。否则,每个其他类都可以充当包装器,甚至是像
int[]
这样长度为 1 的数组。"Pass-by..." is reserved in Java and C. Beyond this, if you intend to change a wrapper instance of a primitive given as reference, this is done by reflection. Example for
Integer
.Output is 6 as in your C++ example. Reflection is required, because Java design considers primitive wrappers as immutable. Else every other class can serve as wrapper, even an array like
int[]
of length 1 .我们在 checkPassByValue 中设置 a = 5,但它没有反映在 a 的值中。
类似地,当我们传递一个人时,我们可以使用 Person.setName 更新该人指向的数据,但是如果更改该人并使其引用一个新的 Person() 在这种情况下,更新将不会反映在主函数中
We set a = 5 in the checkPassByValue but it is not reflected in the value of a.
Similarly, when we pass a person we can update the data where the person points to by using Person.setName however if change the person and make it refer to a new Person() in that case that update will not be reflected in the main function