Java中的参数传递

为了便于理解,会将参数传递分为按值传递和按引用传递。按值传递是传递的值的拷贝,按引用传递传递的是引用的地址值,所以有“在java里参数传递都是按值传递”、“引用也是按值传递的”这些说法。

基本数据类型作为参数传递

基本数据类型作为参数传递时都是传递值的拷贝。 指的是方法调用中,传递的是值的拷贝,无论怎么改变这个拷贝,原值是不会改变的。

也即是说实参把它的值传递给形参,对形参的改变不会影响实参的值。

public class Test {
    public static void main(String[] args) {
        Test test1 = new Test();
        int i = 5;
        System.out.println("调用前的i=" + i);
        test1.testPassParameter(i);
        //传递后,testPassParameter方法中对形参i的改变不会影响这里的i
        System.out.println("调用后的i=" + i);
    }
    public void testPassParameter(int i) {
        i = 10;//这里只是对形参的改变
        System.out.println("tpp方法中的i=" + i);
    }
}

输出结果

调用前的i=5
tpp方法中的i=10
调用后的i=5

对象作为参数传递

对象作为参数传递时,在方法内改变对象的值,有时原对象跟着改变,而有时又没有改变。就会让人对“传值”和“传引用”产生疑惑。

先看看两种情况的例子。

public class Test {
    public static void main(String[] args) {
        StringBuffer s1 = new StringBuffer("hello");
        StringBuffer s2 = new StringBuffer("hello");
        changeStringBuffer(s1, s2);
        System.out.println("s1=" + s1);
        System.out.println("s2=" + s2);
    }
    public static void changeStringBuffer(StringBuffer ss1, StringBuffer ss2) {
        ss1.append("world");
        ss2 = ss1;
    }
}

输出结果:

s1=helloworld  
s2=hello

分析如下:

//(1)s1,s2指向字符串的地址不同,假设为地址1,地址2
StringBuffer s1 = new StringBuffer("hello");
StringBuffer s2 = new StringBuffer("hello");
image
//(2)调用changeStringBuffer方法
changeStringBuffer(s1, s2);
//调用后会将s1,s2的地址(地址1,地址2)传给ss1,ss2,即现在ss1也指向地址1,ss2也指向地址2
image
//(3)ss1所指向字符串的值变为helloworld,调用者s1的值相应变化。
ss1.append("world");
//ss2将指向ss1指向的地址(地址1),但此时s2依旧指向地址2,s2的值在调用前后不变。
ss2 = ss1;
image

所以,s1的输出为helloworld,s2的输出结果为hello。

(注意,这里为了区分,s1,s2和ss1,ss2用了不同的名称,但有时候形参与实参的名字相同,其实两者变量是完全不同的,一个是main方法中的变量,一个是changeStringBuffer()中的变量。)

可以看出,在java中对象作为参数传递时,传递的是引用的地址,是把对象在内存中的地址拷贝了一份传给了参数

拓展:

基本数据类型的包装类型在传递参数时其实也是“按引用传递的”,只是因为包装类型变量都是不可变量,容易误解。

String是final类型,是个特殊的类,对它的一些操作符是重载的。比如:

String str = "hello";//等价于String str=new String("hello");

 String str = "hello";
        str = str + "world";//等价于str = new String(new StringBuffer(str).append("world"));

从以上分析,现在可以更易理解下面的代码:

public class Test {
    public static void fun(String str, char ch[]) {
        str = "world";
        ch[0] = 'd';
    }
    public static void main(String[] args) {
        String str = new String("hello");
        char[] ch = {'a', 'b', 'c'};
        fun(str, ch);
        System.out.println(str);
        System.out.println(ch);
    }
}

输出结果

hello  
dbc

方法调用时,名称相同的实参和形参并不一样,一个是main()中的str,指向存放"hello"的内存地址。一个是fun()中的str,str="world",相当于new String("world")。String是final类型,将在堆中重新分配一个内存空间存放"world"。ch[0]='d',对象的内容发生改变。

image

所以main()中str变量存放的对象内容依然是"hello"。ch从"abc"变为"dbc"。

参考:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,547评论 4 374
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,787评论 2 308
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 112,175评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,752评论 0 223
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,169评论 3 297
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,056评论 1 226
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,195评论 2 321
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,980评论 0 214
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,724评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,872评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,344评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,667评论 3 264
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,379评论 3 245
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,202评论 0 9
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,992评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,189评论 2 286
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,987评论 2 279

推荐阅读更多精彩内容

  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy阅读 9,455评论 1 51
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,301评论 18 399
  • __block和__weak修饰符的区别其实是挺明显的:1.__block不管是ARC还是MRC模式下都可以使用,...
    LZM轮回阅读 3,209评论 0 6
  • 患难见真情这句话实在不错,虽然我没有资格要求别人为我牺牲,但是当遇到困难时,寻遍四处握住那唯一一双伸出的援手,那一...
    易张氏阅读 112评论 0 1
  • 她说谎 说一个夜晚有二十个钟头那么长 说天上的星星 来回地跑 说没有天明 天明被遗落在 一个男人的头发上 被带走,...
    弭路阅读 225评论 0 2