好的,在你跳到腳之前,你需要了解與傳遞通過相比傳遞值是多少。您可能不同意這種按值傳遞的定義,但這只是語義,因爲真正的問題是堆棧分配和堆分配之間發生的問題。傳遞值作爲參考返回時會發生什麼?
傳遞值:要傳遞的對象被複制並且該對象的副本作爲參數提交給函數(OK,OO純粹主義者稱你稱它爲「方法」 - 語義!)。因此,在函數結束/返回時,不管對象副本做了什麼,原始對象都不會被修改。
所以Java(也可能是C#)是一種傳值語言。有些人認爲他們是通過引用,但實際上傳遞的參數是引用。所以引用的副本被傳遞給函數。也就是說,引用是按值傳遞的arg,因爲在函數的結尾/返回時原始引用不會更改。
既然我們已經完成了這項工作,並接受我的價值傳遞,那麼這裏就是一個問題。
所以一個函數參數是原始對象/引用的副本。它被分配在堆棧上。堆棧很好,因爲分配的值只是在函數結束/返回時立即丟棄。當我的函數從棧中傳遞值arg並返回它時會發生什麼。看,它在堆棧上。該對象/引用的堆棧分配是否被複制並重新分配到堆上?
Java和C#中究竟發生了什麼/精確的事情?
如果您進入並刪除「無論如何總是在堆棧上創建的結構」,我將刪除downvote。這根本不是事實。首先,如果結構是一個類的成員,它住在哪裏?有關更多信息,請參閱:http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value-types.aspx http://blogs.msdn.com/b/ ericlippert/archive/tags/value + types/ –
@Anthony:他實際上是對的,當'newobj' MSIL指令被用來創建一個結構實例時,新的對象留在堆棧上。 [「但是,newobj指令可用於在堆棧上創建值類型的新實例」](http://msdn.microsoft.com/zh-cn/library/system.reflection.emit.opcodes.newobj .aspx)當然,並不是所有的值類型實例都在堆棧上創建,但是使用'newobj'創建的實例是。 –
@Sid:你的錯誤忽略了引用變量本身,它與它所指向的類實例是截然不同的。引用變量可以在堆棧上,就像問題所聲明的一樣。 –