<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>http://wiki.eijux.com/index.php?action=history&amp;feed=atom&amp;title=%E4%B8%BA%E4%BB%80%E4%B9%88%E8%AF%B4Java%E4%B8%AD%E5%8F%AA%E6%9C%89%E5%80%BC%E4%BC%A0%E9%80%92%EF%BC%9F</id>
	<title>为什么说Java中只有值传递？ - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.eijux.com/index.php?action=history&amp;feed=atom&amp;title=%E4%B8%BA%E4%BB%80%E4%B9%88%E8%AF%B4Java%E4%B8%AD%E5%8F%AA%E6%9C%89%E5%80%BC%E4%BC%A0%E9%80%92%EF%BC%9F"/>
	<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=%E4%B8%BA%E4%BB%80%E4%B9%88%E8%AF%B4Java%E4%B8%AD%E5%8F%AA%E6%9C%89%E5%80%BC%E4%BC%A0%E9%80%92%EF%BC%9F&amp;action=history"/>
	<updated>2026-04-25T15:25:31Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.38.2</generator>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=%E4%B8%BA%E4%BB%80%E4%B9%88%E8%AF%B4Java%E4%B8%AD%E5%8F%AA%E6%9C%89%E5%80%BC%E4%BC%A0%E9%80%92%EF%BC%9F&amp;diff=6243&amp;oldid=prev</id>
		<title>Eijux：​/* 形参 与 实参 */</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=%E4%B8%BA%E4%BB%80%E4%B9%88%E8%AF%B4Java%E4%B8%AD%E5%8F%AA%E6%9C%89%E5%80%BC%E4%BC%A0%E9%80%92%EF%BC%9F&amp;diff=6243&amp;oldid=prev"/>
		<updated>2022-11-07T10:52:33Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;形参 与 实参&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;zh-Hans-CN&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;←上一版本&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;2022年11月7日 (一) 18:52的版本&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l7&quot;&gt;第7行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第7行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== 形参 与 实参 ===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== 形参 与 实参 ===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;# '''形式参数'''&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;：是在定义函数名和函数体的时候使用的参数，目的是用来接收调用该函数时传入的参数。【参数的展位符】&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;# '''形式参数'''&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;：是在定义函数名和函数体的时候使用的参数，目的是用来接收调用该函数时传入的参数。【参数的占位符】&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;# '''实际参数'''：在主调函数中调用一个函数时，函数名后面括号中的参数称为“实际参数”。【参数的真实内容】&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;# '''实际参数'''：在主调函数中调用一个函数时，函数名后面括号中的参数称为“实际参数”。【参数的真实内容】&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
	<entry>
		<id>http://wiki.eijux.com/index.php?title=%E4%B8%BA%E4%BB%80%E4%B9%88%E8%AF%B4Java%E4%B8%AD%E5%8F%AA%E6%9C%89%E5%80%BC%E4%BC%A0%E9%80%92%EF%BC%9F&amp;diff=5525&amp;oldid=prev</id>
		<title>Eijux：​创建页面，内容为“category:Java  == 关于 ==  调用一个有参函数的时候，会把实际参数传递给形式参数。    但是，在程序语言中，这个传递过程中传递的两种情况，即值传递和引用传递。  === 形参 与 实参 === # '''形式参数'''：是在定义函数名和函数体的时候使用的参数，目的是用来接收调用该函数时传入的参数。【参数的展位符】 # '''实际参数'''：在主调函数中调用一…”</title>
		<link rel="alternate" type="text/html" href="http://wiki.eijux.com/index.php?title=%E4%B8%BA%E4%BB%80%E4%B9%88%E8%AF%B4Java%E4%B8%AD%E5%8F%AA%E6%9C%89%E5%80%BC%E4%BC%A0%E9%80%92%EF%BC%9F&amp;diff=5525&amp;oldid=prev"/>
		<updated>2022-04-30T20:20:22Z</updated>

		<summary type="html">&lt;p&gt;创建页面，内容为“&lt;a href=&quot;/%E5%88%86%E7%B1%BB:Java&quot; title=&quot;分类:Java&quot;&gt;category:Java&lt;/a&gt;  == 关于 ==  调用一个有参函数的时候，会把实际参数传递给形式参数。    但是，在程序语言中，这个传递过程中传递的两种情况，即值传递和引用传递。  === 形参 与 实参 === # &amp;#039;&amp;#039;&amp;#039;形式参数&amp;#039;&amp;#039;&amp;#039;：是在定义函数名和函数体的时候使用的参数，目的是用来接收调用该函数时传入的参数。【参数的展位符】 # &amp;#039;&amp;#039;&amp;#039;实际参数&amp;#039;&amp;#039;&amp;#039;：在主调函数中调用一…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;[[category:Java]]&lt;br /&gt;
&lt;br /&gt;
== 关于 ==&lt;br /&gt;
 调用一个有参函数的时候，会把实际参数传递给形式参数。&lt;br /&gt;
 &lt;br /&gt;
 但是，在程序语言中，这个传递过程中传递的两种情况，即值传递和引用传递。&lt;br /&gt;
&lt;br /&gt;
=== 形参 与 实参 ===&lt;br /&gt;
# '''形式参数'''：是在定义函数名和函数体的时候使用的参数，目的是用来接收调用该函数时传入的参数。【参数的展位符】&lt;br /&gt;
# '''实际参数'''：在主调函数中调用一个函数时，函数名后面括号中的参数称为“实际参数”。【参数的真实内容】&lt;br /&gt;
&lt;br /&gt;
示例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
public class NormalTest {&lt;br /&gt;
    public void print(String str){  // 形参为 str&lt;br /&gt;
        System.out.println(str);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        NormalTest nt = new NormalTest();&lt;br /&gt;
        nt.print(&amp;quot;Eijux&amp;quot;);  // 实参为 &amp;quot;Eijux&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 值传递 与 引用传递 ===&lt;br /&gt;
# '''值传递'''（pass by value）：在调用函数时将'''复制的实参值'''传递到函数中；&lt;br /&gt;
#* 函数中对参数进行的修改，'''不会影响实参'''。&lt;br /&gt;
# '''引用传递'''（pass by reference）：在调用函数时将'''实参地址'''直接传递到函数中；&lt;br /&gt;
#* 函数中对参数进行的修改，'''将影响到实参'''。&lt;br /&gt;
&lt;br /&gt;
示例：&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
public class NormalTest {&lt;br /&gt;
    public void print(int j) {&lt;br /&gt;
        j = 20;&lt;br /&gt;
        System.out.println(&amp;quot;print in pass , j is &amp;quot; + j);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        NormalTest nt = new NormalTest();&lt;br /&gt;
        int i = 10;&lt;br /&gt;
        nt.print(i);&lt;br /&gt;
        System.out.println(&amp;quot;print in main , i is &amp;quot; + i);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
: &amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
print in pass , j is 20&lt;br /&gt;
print in main , i is 10&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== “值传递”的理解 ==&lt;br /&gt;
关于“值传递”，有几个常见的错误理解：&lt;br /&gt;
# （参数类型）如果传递的是“普通类型”，那就是“值传递”；如果传递的是“对象类型”，那就是“引用传递”。&lt;br /&gt;
# （参数内容）“值传递”和“引用传递”的区别是“传递的内容”：如果是个值，就是值传递；如果是个引用，就是引用传递。&lt;br /&gt;
&lt;br /&gt;
=== 辨析 ===&lt;br /&gt;
# 示例一：（错误理解）&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; highlight=&amp;quot;3&amp;quot;&amp;gt;&lt;br /&gt;
public class NormalTest {&lt;br /&gt;
    public void print(User user) {&lt;br /&gt;
        user.setName(&amp;quot;Xuelinzi&amp;quot;);&lt;br /&gt;
        System.out.println(&amp;quot;print in pass , user is &amp;quot; + user);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        NormalTest nt = new NormalTest();&lt;br /&gt;
        User usr = new User();&lt;br /&gt;
        usr.setName(&amp;quot;Eijux&amp;quot;);&lt;br /&gt;
        usr.setGender(&amp;quot;Male&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        nt.print(usr);  // 传递实参 usr&lt;br /&gt;
        System.out.println(&amp;quot;print in main , user is &amp;quot; + usr);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    static class User{&lt;br /&gt;
        private String name;&lt;br /&gt;
        private String gender;&lt;br /&gt;
&lt;br /&gt;
        public void setName(String name){ this.name = name; }&lt;br /&gt;
        public void setGender(String gender){ this.gender = gender; }&lt;br /&gt;
&lt;br /&gt;
        @Override&lt;br /&gt;
        public String toString() {&lt;br /&gt;
            return &amp;quot;User{&amp;quot; +&lt;br /&gt;
                    &amp;quot;name='&amp;quot; + name + '\'' +&lt;br /&gt;
                    &amp;quot;, gender='&amp;quot; + gender + '\'' +&lt;br /&gt;
                    '}';&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
print in pass , user is User{name='Xuelinzi', gender='Male'}&lt;br /&gt;
print in main , user is User{name='Xuelinzi', gender='Male'}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: 如上所示：看似是在 print 方法中，将实参 usr 改变了，好像是“如果传递的是对象类型，那就是引用传递”，或“传递的内容是个引用，就是引用传递”。&lt;br /&gt;
# 示例二：（辨析理解）&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; highlight=&amp;quot;3-4&amp;quot;&amp;gt;&lt;br /&gt;
public class NormalTest {&lt;br /&gt;
    public void pass(User user) {&lt;br /&gt;
        user = new User();&lt;br /&gt;
        user.setName(&amp;quot;Xuelinzi&amp;quot;);&lt;br /&gt;
        user.setGender(&amp;quot;Male&amp;quot;);&lt;br /&gt;
        System.out.println(&amp;quot;print in pass , user is &amp;quot; + user);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public static void main(String[] args) {&lt;br /&gt;
        NormalTest nt = new NormalTest();&lt;br /&gt;
        User usr = new User();&lt;br /&gt;
        usr.setName(&amp;quot;Eijux&amp;quot;);&lt;br /&gt;
        usr.setGender(&amp;quot;Male&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        nt.pass(usr);  // 传递实参 usr&lt;br /&gt;
        System.out.println(&amp;quot;print in main , user is &amp;quot; + usr);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    static class User{&lt;br /&gt;
        private String name;&lt;br /&gt;
        private String gender;&lt;br /&gt;
&lt;br /&gt;
        public void setName(String name){ this.name = name; }&lt;br /&gt;
        public void setGender(String gender){ this.gender = gender; }&lt;br /&gt;
&lt;br /&gt;
        @Override&lt;br /&gt;
        public String toString() {&lt;br /&gt;
            return &amp;quot;User{&amp;quot; +&lt;br /&gt;
                    &amp;quot;name='&amp;quot; + name + '\'' +&lt;br /&gt;
                    &amp;quot;, gender='&amp;quot; + gender + '\'' +&lt;br /&gt;
                    '}';&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
#: &amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot; highlight=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
print in pass , user is User{name='Xuelinzi', gender='Male'}&lt;br /&gt;
print in main , user is User{name='Eijux', gender='Male'}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
两个示例的执行过程：&lt;br /&gt;
# 在 main 中：&lt;br /&gt;
## 创建 User 对象时，会在堆中开辟一块内存（0x11111111），并交由 usr 指向到该内存地址；&lt;br /&gt;
## 调用 pass 方法时，会将“实参”（usr）传递给“形参”（user），此时“usr”、“user”都将会指向内存（0x11111111）。&lt;br /&gt;
# 在 pass 中：&lt;br /&gt;
## 若直接调用“user.setName()”等方法，则将会修改内存（0x11111111）中的内容；&lt;br /&gt;
## 若首先调用“user = new User();”方法，则将在堆中重新开辟一块内存（0x22222222），并将“形参”（user）指向该新内存地址；&lt;br /&gt;
##: 此时再调用“user.setName()”等方法，则将会修改内存（0x22222222）中的内容；&lt;br /&gt;
: 所以：传递“对象类型”时，是把“实参”对象所引用的“'''内存地址'''”当做值传递给了“形参”。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
而输出内容的差别，则是因为：&lt;br /&gt;
# 示例一，输出不同：通过“形参”（由于值传递，指向与“实参”相同的内存），修改了'''内存地址中所存储的数据'''。&lt;br /&gt;
#* 修改的是内存中的数据，并没有修改“形参”，更没有影响到“实参”；&lt;br /&gt;
# 示例二，输出相同：修改“形参”（由于 new，指向了与“实参”不同的内存），输出内容也分别是两个内存块的数据（独立，但属性相同）。&lt;br /&gt;
#* 修改的是“形参”，而并没有影响到“实参”；&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 由此可以看出：&lt;br /&gt;
     &amp;lt;big&amp;gt;'''无论是传递“普通类型”还是“对象类型”，所使用的都是“值传递”'''。&amp;lt;/big&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 同时可以看出：&lt;br /&gt;
     &amp;lt;big&amp;gt;'''值传递和引用传递的区别，是实参到底有没有被复制一份给形参'''，而不是并不是传递的内容（如上：传递引用，仍然是“值传递”）&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 按共享传递 ==&lt;br /&gt;
 无论是值传递还是引用传递，其实都是一种'''求值策略'''（Evaluation strategy），在求值策略中，还有一种叫做按“'''共享传递'''”（call by sharing）。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
其实 Java 中的参数传递严格意义上说应该是：'''按共享传递'''。&lt;br /&gt;
&lt;br /&gt;
 按共享传递——是指在调用函数时，传递给函数的是“实参的地址的拷贝”（如果实参在栈中，则直接拷贝该值）。&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 在函数内部对参数进行操作时，需要先拷贝的地址寻找到具体的值，再进行操作：&lt;br /&gt;
 &lt;br /&gt;
     1、如果原值在栈中（实参值即为栈中值），那么直接拷贝该值。&lt;br /&gt;
         ——'''因为是直接拷贝的值，所以函数内部对参数进行操作不会对外部变量产生影响'''。&lt;br /&gt;
 &lt;br /&gt;
     2、如果原值在堆中（实参值为堆中的地址），则需先根据该地址找到堆中对应的位置，再进行操作。&lt;br /&gt;
         ——'''因为传递的是地址的拷贝，所以函数内对值的操作对外部变量是可见的'''。（如上一节的示例）&lt;br /&gt;
&lt;br /&gt;
总之：&lt;br /&gt;
* Java 中的传递，是值传递，而这个值，实际上是对象的引用。&lt;br /&gt;
*“按共享传递”可以看作“按值传递”的一个特例。&lt;/div&gt;</summary>
		<author><name>Eijux</name></author>
	</entry>
</feed>