关于 java 的传址和传值

2014-09-02 10:02:04 +08:00
 buptlee
我写了一个函数:
public void updateDistMatrix(HashMap<Integer ,LinkedList<Node> > dist_matrix,ArrayList<Integer> nearestNodePair,HashMap<Integer,ArrayList<Integer>> clusterSet)
{
doSomething(dist_matrix);
doSomething(clusterSet);
}
函数是要对传进去的两个参数dist_matrix和clusterSet进行更新,外层是一个循环,不断的调用updateDistMatrix()这个函数,以达到不断更新dist_matrix,clusterSet这两个变量的目的。
但是,我发现,函数里对这两个变量的修改并不能保留到下次迭代,也就是说,下次迭代时,这两个变量的值依然是它们的初始值,我想问下大家,如果我想实现类似于c++的传址(参数)的效果,应该怎么做呢,将dist_matrix,clusterSet在main()前面声明成public static 类型的可以吗?
大神们,教教我。
3939 次点击
所在节点    程序员
15 条回复
jinyang656
2014-09-02 10:14:33 +08:00
不知道你方法体里怎么操作的,java中除了几种基本数据类型之外都是传引用的。
buptlee
2014-09-02 10:21:18 +08:00
@jinyang656
程序里面就是对dist_matrix和clusterSet进行一些修改。
传递引用的意思是不是,传递实参的一个副本,因此对实参的修改不会反应到传进去的参数上?
那如果我希望这种修改能保留,应该怎么做?就像c++的传址那样。thanks.
chocotan
2014-09-02 10:42:59 +08:00
难道楼主在doSomething里这样了.... dist_matrix=new XXX...
shuson
2014-09-02 10:46:07 +08:00
main() 声明static没用吧。
试试update后return一下?
Aegwynn
2014-09-02 10:55:14 +08:00
java根本没有传址的说法,这个是人们从C那边搬过来的概念。

java里面只有传值,不同在于:对基本数据类型,值就是它自身的值;其他是传引用的值。

想要改变对象的值,就不要去改变它的引用即可。
defaultuser
2014-09-02 10:57:28 +08:00
@Aegwynn 说的对
buptlee
2014-09-02 11:08:40 +08:00
@chocotan 没有,就是拿出dist_matrix里面的某些键值对做了修改,然后重新插入到dist_matrix里面。
buptlee
2014-09-02 11:12:52 +08:00
@shuson 可是我有两个实参变量啊。两个都要改变,不能return两个变量吧,毕竟不是Python。
buptlee
2014-09-02 11:16:09 +08:00
@Aegwynn 能解释一下,“想要改变对象的值,就不要去改变它的引用即可。”这句话的意思吗,thanks。我的逻辑是这样的:
while(clusterSet.size()>3){
updateDistMatrix(dist_matrix,clusterSet);
}
当然,每次循环,updateDistMatrix()函数体里面有减少clusterSet项数的逻辑。
jamiesun
2014-09-02 11:18:15 +08:00
试试不要用函数包裹,直接在循环里顺序执行

doSomething(dist_matrix);
doSomething(clusterSet);


八成是方法里改变了引用。
buptlee
2014-09-02 11:22:51 +08:00
@jamiesun 好的,我试试不要函数包裹。
能不能解释一下,改变了引用具体是指什么呢,刚刚用java不久,好多概念也是边做边学,见笑啦。
Aegwynn
2014-09-02 11:23:40 +08:00
@buptlee updateDistMatrix这个方法的源代码都贴出来看看,主要是对clusterSet的操作部分。

另外建议public void updateDistMatrix(HashMap<Integer ,LinkedList<Node> > dist_matrix,ArrayList<Integer> nearestNodePair,HashMap<Integer,ArrayList<Integer>> clusterSet)
的方法签名改成
public void updateDistMatrix(Map<Integer ,List<Node> > dist_matrix,List<Integer> nearestNodePair,Map<Integer,List<Integer>> clusterSet)
shuson
2014-09-02 11:34:14 +08:00
@buptlee 对,如果要返回两个值,就不值当再封装后返回了。
看了回复们,我也是觉得doSomething函数中可能改变了参数的引用,类似重新创建了新的引用并update的是这个新引用,导致原来传入的参数的引用没有被方法执行操作。
buptlee
2014-09-02 11:35:13 +08:00
已经贴出来啦,方法签名改成map和list之后有啥好处呢,是不是为了多态?效率上能有所提高吗?thanks
gangsta
2014-09-02 11:37:29 +08:00
sof上的经典问题:
Is Java “pass-by-reference” or “pass-by-value”?

http://stackoverflow.com/q/40480/1299675

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/131233

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX