在java中将对象传递给方法似乎是通过引用(而Java是通过val)
我认为当你将对象传递给 Java 中的方法时,它们应该是按值传递的。
这是我的代码:
public class MyClass{
int mRows;
int mCols;
Tile mTiles[][]; //Custom class
//Constructor
public MyClass(Tile[][] tiles, int rows, int cols) {
mRows = rows;
mCols = cols;
mTiles = new Tile[mRows][mCols];
for (int i=0; i < mRows; i++) {
for (int j=0; j < mCols; j++) {
mTiles[i][j] = new Tile();
mTiles[i][j] = tiles[i][j];
}
}
}
此时,对 mTiles
对象的任何更改都会反映回tiles 对象。有什么想法如何解决这个问题吗?
谢谢大家。
I thought when you passed objects to methods in Java, they were supposed to be by value.
Here is my code:
public class MyClass{
int mRows;
int mCols;
Tile mTiles[][]; //Custom class
//Constructor
public MyClass(Tile[][] tiles, int rows, int cols) {
mRows = rows;
mCols = cols;
mTiles = new Tile[mRows][mCols];
for (int i=0; i < mRows; i++) {
for (int j=0; j < mCols; j++) {
mTiles[i][j] = new Tile();
mTiles[i][j] = tiles[i][j];
}
}
}
At this point, any changes to the mTiles
object are reflected back to the tiles object. Any ideas how to fix this?
Thanks all.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
它是通过 val 实现的,但是当谈论对象时,传递的是引用的值,因此,如果您的对象是可变的(如您的示例中所示),则通过引用副本修改对象,将修改底层对象。
要解决这个问题,您必须复制对象并传递新的引用值。
在您的代码中,您在“tiles”和“mTiles”中使用相同的参考值,
您必须创建一个像这样的新值:
Or
Or
或者类似的东西,这样您实际上可以创建一个新的值,而不是使用相同的参考号。
我希望这有帮助。
编辑
当你改变 pass-by-val 中的 ref 时,原来的不受影响,即:
在此之后,原来的“hi”仍然是“hi”。在 pass-by-ref 中,它将是“再见”
这里有一些链接:
http://www.javaranch.com/campfire/StoryPassBy.jsp" javaranch.com/campfire/StoryPassBy.jsp
有人可以向我解释一下 Java 中通过“值”而不是“引用”传递的原因是什么吗?
按引用传递还是按值传递?
http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass .html
http://academic.regis.edu/dbahr/ GeneralPages/IntroToProgramming/JavaPassByValue.htm
http://www.jguru .com/faq/view.jsp?EID=430996
最终:
http://www.google.com.mx/search?sourceid=chrome&ie=UTF-8&q=java+is+pass+by +值
It is by val, but when talking about objects, what gets passed is the value of the reference, so, if your object is mutable ( as in your example ) modifying the object through the reference copy, will modify the underlaying object.
To solve it, you have to copy your object and pass that new reference value.
In your code, you are using the same reference value in "tiles" and in "mTiles"
You would have to create a new one like this:
Or
Or
Or something like that, so you can create actually a new one, instead of using the same ref.
I hope this helps.
EDIT
When you change the ref in pass-by-val, the original is not affected, ie:
After this, the original "hi" is still "hi". In pass-by-ref it would be "bye"
Here some links:
http://www.javaranch.com/campfire/StoryPassBy.jsp
Can someone explain to me what the reasoning behind passing by "value" and not by "reference" in Java is?
Pass by reference or pass by value?
http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html
http://academic.regis.edu/dbahr/GeneralPages/IntroToProgramming/JavaPassByValue.htm
http://www.jguru.com/faq/view.jsp?EID=430996
An ultimately:
http://www.google.com.mx/search?sourceid=chrome&ie=UTF-8&q=java+is+pass+by+value
您不传递对象,而是传递对该对象的引用,该引用是按值复制的。
You don't pass the object, you pass a references to the object, which is copied by value.
以下是 Java 参数传递语义的一些诊断示例:
对于对象类型:
对于原始类型:
事实上,在这两个示例中,
changeIt
方法中的赋值仅影响相应方法的局部变量,实际打印的值将是“hi”和“0”。编辑
并且由于OP仍然不相信我......这里有一个诊断示例,表明Java也是可变对象的按值调用。
相比之下,此示例对于按引用调用和按值调用语义将给出相同的答案。它没有证明任何关于参数传递语义的事情。
相信我,我从事 Java 编程已经超过 1 年了。十年来,我教授大学水平的比较编程语言课程。
Here are some diagnostic examples for Java's argument passing semantics:
For an object type:
For a primitive type:
In fact, in both of those examples, the assignments within the
changeIt
methods only affect the respective method's local variable, and the actual values printed will be "hi" and "0".EDIT
And since the OP still doesn't believe me ... here's a diagnostic example to show that Java is call-by-value for mutable objects as well.
By contrast, this example will give the same answer for both call by reference and call by value semantics. It doesn't prove anything about argument passing semantics.
Trust me, I've been programming Java for > 10 years, and I've taught comparative programming language courses at university level.
事实上,Java 是按值传递的。但它也有“引用数组”!这就是为什么许多人认为 Java 对于对象(至少对于数组)是按引用传递,而对于基元仅是按值传递。
这是一个简短的测试:
无论您是克隆还是使用 =,System.out.print 总是如下所示:
这证明克隆和数组是有害的组合,因为数组只存储指针!我仍然需要测试这对于无数组对象是否也成立...因为这意味着 Java 始终是“按引用存储”(并且“克隆”函数对于任何对象来说只是一个糟糕的笑话包含数组),而只有基元是实值,没有引用!
因为我们知道逻辑:按引用存储 x 按值传递 == “按值存储 x 按引用传递”(对于对象!),
而我们从学校起就已经知道:按值存储 x按值传递(对于原语)
那么,我们都被我们的编程老师欺骗了吗(即使在大学)?也许吧,但他们至少没有犯任何逻辑错误……所以这不是谎言,只是错误的。
编辑
我用一个类编写了与上面相同的代码,首先是数据结构:
现在是控制器:
测试结果总是这样 - 无论我使用=还是clone():
现在我“主阵”已收入囊中,立刻就能主宰一切物体! (这并不是一件好事)
我总是对Java数组感到不安,但我又说不出来它是什么。现在我知道了,我感觉很好,因为从那时起我只使用数组作为对象的容器......只是发现自己非常惊讶它们在像 PHP 这样的脚本语言中是多么重要!
尽管如此,Java 数组仍然非常适合线程之间的同步,因为您可以轻松地传递它们并且仍然可以访问共享值。但是来自 PHP 或 C++ 或其他地方的程序员确实可能会遇到 Java 数组的一些问题。 ;D
哦,我喜欢这篇文章:http://javadude.com/articles/passbyvalue.htm
更新:我找到了一个很好的解决方案来复制任何包含数组的对象,请参阅我的评论:使用 Object.clone() 时出现错误
As a matter of fact, Java is pass-by-value. But it also has "arrays-by-reference"! That's why many people think Java is pass-by-reference for objects (at least for arrays) and only pass-by-values for primitives.
Here is a short test:
No matter if you clone or use =, the System.out.print will always look like this:
This proves that cloning and arrays are a harmful combination, because arrays only store pointers! I still need to test if this is also true for no-array objects...because this would mean that Java is always "storage-by-reference" (and the "clone"-function would be only a bad joke for any objects containing arrays), while only primitives are real values and no references!
And since we know about logic: storage-by-reference x pass-by-value == "storage by value x pass-by-reference" (for objects!),
while we already knew since school: storage-by-value x pass-by-value (for primitives)
So, were we all lied to by our programming teachers (even at university)? Maybe, but they didn't make any logical errors at least...so it wasn't a lie, it was just wrong.
EDIT
I wrote the same code as above with a class, first the data structure:
Now the controller:
The test results will always look like that - no matter if I use = or clone():
Now I've got the "master array" in the pocket, with whom I can rule all objects right away! (which isn't really a good thing)
I always felt uneasy about Java arrays, but I couldn't say what it was. Now I know it, and I feel good since I only used arrays as container for objects ever since...only to find myself being quite surprised how important they are in script languages like PHP!
Still, Java arrays are great for synchronisation between threads, as you can pass them easily and still access shared values. But programmers coming from PHP or C++ or somewhere else may indeed experience some problems with Java arrays. ;D
Oh, I like this article: http://javadude.com/articles/passbyvalue.htm
UPDATE: I've found a great solution to copy any object containing arrays, see my commentary here: Bug in using Object.clone()