作者qrtt1 (thinking in java)
看板java
标题Re: [问题] 问一个 记忆体 和 GC 的问题
时间Tue Jan 31 23:25:44 2006
※ 引述《jackyhuang (雪.狼.湖)》之铭言:
: ※ 引述《qrtt1 (thinking in java)》之铭言:
: : java的传值对原生型态来说是call by value
: : 型态多大产生多大的副本
: : 对reference来说,不是传副本。
: : 是reference alias,是别名
: : 所以不管原物件多大,都增加一个reference的大小
: 根据在JLS中的定义中,Java只有call by value
: 而传reference type时,就是把那个reference value复制
: 所以也是传副本,其实与传primitive types没有差异
: (reference value一词在JLS 4.1中出现)
: 用到"reference alias",我认为反而会容易让人混乱,
: 会让人认为是原本的reference的alias (reference's alias)
: 因为根据"alias"这个字的意思,就是你对这个东西动作等同於对原本的
: 那这样一来你在method中对传进来的东西做下面的事
: obj.method(x); //某个地方call了下面这个method
: ------------------------------------------------
: public void method(Object y) {
: y = null; //若此y是前面x的alias,
: //那麽在y上的动作等於在x上
: }
: 会让人误以为会把原始的argument设为null
: 我想要说的只是,使用"alias"这个字很容易让人误解
: 我在google查了"alias"这个字的意思,但找不到简单明了的解释
: 所以我就拿C++ Primer中对alias的描述
: "A reference is an Alias"
: "Because a reference is just another name for the object to which
: it is bound, all operations on a reference are actually operations on
: the underlying object to which the reference is bound."
: (此处object代表东西,不是我们一般Java认知的物件)
: 虽然在C++与Java中的reference不尽相同,但其中可以看出
: alias这个词就是等同於对原本的"underlying object"动作,
: 所以如果依此去解释"传reference type时就是传reference alias"
: 那麽就会出现上面这种错误的推论了~
: 我的建议是,尽量使用JLS中所用的词,因为Java与C++有些东西同名不同义
: 在讨论时容易造成误解,其实Java的行为是比较简单,总之就是call by value
: 什麽都是传副本,只是看你今天要传的是"primitive value"的副本,
: 还是"reference value"的副本。
alias是很重要的一个观念。
因为若不了解则在使用物件时可能隐藏了bug
详细解说请参考thinking in java,前面介绍reference的章节,
与附录介绍clone的章节
此外,
<%
: public void method(Object y) {
: y = null; //若此y是前面x的alias,
: //那麽在y上的动作等於在x上
: }
%>
java中唯一有operator overload的物件只有String
唯一合法改变物件内容的方使是呼叫其公用方法(或其他许可的情况)
我将原生变数与物件参考分开讲是基於实际上的结果
原生变数的副本并不能互相影响, 是独立的
而物件参考的副本, 就是别名。会不会互相影响视其是否为可变动物件而定。
若要其互相独立需执行clone方法。
ps. 令y=null正好让我回想起一个可呼应原旨的想法
依Practical Java建议, 希望GC快点收回不用的空间时
较好的方法是不再使用的物件为null :)
--
不怕名词多而混淆, 只怕自己辞不达义而已。
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 210.243.48.61