写点什么

天真,居然还有人认为 java 的参数传递方式是引用传递,互联网 java 工程师面试突击训练网盘

用户头像
极客good
关注
发布于: 刚刚

[](


)引用类型传递


=====================================================================


我们都知道 java 中的 String 类型不属于基本数据类型,它是一个引用类型,也可以说是一个对象,那么它的传递方式是什么呢?


我们还是先来看例子


package com.ymy.param;


/**


  • @ProjectName: demo

  • @Package: com.ymy.param

  • @ClassName: StringTypeTest

  • @Author: 流星 007

  • @Description: String 类型传递

  • csdn:https://blog.csdn.net/qq_33220089

  • 今日头条:https://www.toutiao.com/c/user/5372182357/#mid=1637641735275523

  • @Date: 2020/7/5 14:22

  • @Version: 1.0


*/


public class StringTypeTest {


public static void main(String[] args) {


String a = "hello";


dosomthing(a);


System.out.println("主函数 a 的值 = "+a);


}


private static void dosomthing(String a) {


a = a+" bug";


System.out.println("修改过后,a = "+a);


}


}


打印结果


修改过后,a = hello bug


主函数 a 的值 = hello


Process finished with exit code 0


我们发现主函数的 a 并没有受到 dosomthing 函数的影响,所以这并不是引用传递,这个时候你说是因为


a = a+" bug";这行代码生成了新的对象,所以才会导致数据不一致,我们先来看看 a 的赋值情况吧


// class version 52.0 (52)


// access flags 0x21


public class com/ymy/param/StringTypeTest {


// compiled from: StringTypeTest.java


// access flags 0x1


public <init>()V


L0


LINENUMBER 14 L0


ALOAD 0


INVOKESPECIAL java/lang/Object.<init> ()V


RETURN


L1


LOCALVARIABLE this Lcom/ymy/param/StringTypeTest; L0 L1 0


MAXSTACK = 1


MAXLOCALS = 1


// access flags 0x9


public static main([Ljava/lang/String;)V


// parameter args


L0


LINENUMBER 17 L0


LDC "hello"


ASTORE 1


L1


LINENUMBER 18 L1


ALOAD 1


INVOKESTATIC com/ymy/param/StringTypeTest.dosomthing (Ljava/lang/String;)V


L2


LINENUMBER 19 L2


GETSTATIC java/lang/System.out : Ljava/io/PrintStream;


NEW java/lang/StringBuilder


DUP


INVOKESPECIAL java/lang/StringBuilder.<init> ()V


LDC "\u4e3b\u51fd\u6570a\u7684\u503c = "


INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;


ALOAD 1


INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;


INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;


INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V


L3


LINENUMBER 21 L3


RETURN


L4


LOCALVARIABLE args [Ljava/lang/String; L0 L4 0


LOCALVARIABLE a Ljava/lang/String; L1 L4 1


MAXSTACK = 3


MAXLOCALS = 2


// access flags 0xA


private static dosomthing(Ljava


【一线大厂Java面试题解析+核心总结学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


/lang/String;)V


// parameter a


L0


LINENUMBER 24 L0


NEW java/lang/StringBuilder


DUP


INVOKESPECIAL java/lang/StringBuilder.<init> ()V


ALOAD 0


INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;


LDC " bug"


INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;


INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;


ASTORE 0


L1


LINENUMBER 25 L1


GETSTATIC java/lang/System.out : Ljava/io/PrintStream;


NEW java/lang/StringBuilder


DUP


INVOKESPECIAL java/lang/StringBuilder.<init> ()V


LDC "\u4fee\u6539\u8fc7\u540e\uff0ca = "


INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;


ALOAD 0


INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;


INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;


INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V


L2


LINENUMBER 27 L2


RETURN


L3


LOCALVARIABLE a Ljava/lang/String; L0 L3 0


MAXSTACK = 3


MAXLOCALS = 1


}


这是上面代码的字节码代码,我们可以清楚的看到 a 在赋值的时候都调用了 StringBuilder 的同 String 方法,现在我们来看看这个神奇的同 String 方法。


@Override


public String toString() {


// Create a copy, don't share the array


return new String(value, 0, count);


}


这是 StringBuilder 中的 toString 方法,确实是 new 了一个新的对象,就算是 a 变成了一个新的对象,如果是引用传递,主函数的 a 就不会受影响吗?这点我会讲完对象类型传递之后在进行讲解,请继续往下看。


[](


)对象类型传递


=====================================================================


其实上面的两种其实很好区分,很多人都知道是值传递,很多人说 java 的传递方式是引用传递的原因就是出自这里:传递的参数为对象


有些人看到对象传递的时候会改变主函数的值,就认为 java 的参数传递是引用传递,有些人又因为基本数据类型不会队主函数的值造成修改,所以他们的结论是:基本数据类型为值传递;对象类型为引用传递,想法很好,那我们现在一起来解开对象传递的神秘面纱,它到底是引用传递还是值传递呢?


go go go !!!!


还是老规矩,我们一起来看一个例子


package com.ymy.param.vo;


/**


  • @ProjectName: demo

  • @Package: com.ymy.param.vo

  • @ClassName: LolVo

  • @Author: 流星 007

  • @Description: lol 英雄属性

  • csdn:https://blog.csdn.net/qq_33220089

  • 今日头条:https://www.toutiao.com/c/user/5372182357/#mid=1637641735275523

  • @Date: 2020/7/5 15:11

  • @Version: 1.0


*/


public class LolVo {


/**


  • 姓名


*/


private String name;


/**


  • 职业


*/


private String profession;


public String getName() {


return name;


}


public void setName(String name) {


this.name = name;


}


public String getProfession() {


return profession;


}


public void setProfession(String profession) {


this.profession = profession;


}


@Override


public String toString() {


return "LolVo{" +


"name='" + name + ''' +


", profession='" + profession + ''' +


'}';


}


}


package com.ymy.param;


import com.ymy.param.vo.LolVo;


/**


  • @ProjectName: demo

  • @Package: com.ymy.param

  • @ClassName: ObjectTypeTest

  • @Author: 流星 007

  • @Description: 对象类型传递

  • csdn:https://blog.csdn.net/qq_33220089

  • 今日头条:https://www.toutiao.com/c/user/5372182357/#mid=1637641735275523

  • @Date: 2020/7/5 15:16

  • @Version: 1.0


*/


public class ObjectTypeTest {


public static void main(String[] args) {


LolVo lolVo = new LolVo();


lolVo.setName("无极剑圣");


lolVo.setProfession("刺客");


dosomthing(lolVo);


System.out.println("主函数 lolVo = "+lolVo);


}


private static void dosomthing(LolVo lolVo) {


lolVo.setProfession("战士");


System.out.println("dosomthing lolVo = "+lolVo);


}


}


结果如下:


dosomthing lolVo = LolVo{name='无极剑圣', profession='战士'}


主函数 lolVo = LolVo{name='无极剑圣', profession='战士'}


Process finished with exit code 0

用户头像

极客good

关注

还未添加个人签名 2021.03.18 加入

还未添加个人简介

评论

发布
暂无评论
天真,居然还有人认为java的参数传递方式是引用传递,互联网java工程师面试突击训练网盘