ToB企服应用市场:ToB评测及商务社交产业平台

标题: String类型函数传递问题 [打印本页]

作者: 花瓣小跑    时间: 2022-8-28 03:50
标题: String类型函数传递问题
String类型函数传递问题

问题

结论 (先说结论)

测试数据(为什么会有这个问题, 来源于以下操作)

  1. package timer;
  2. /**
  3. * @author liwangcai E-mail:1252376504@qq.com
  4. */
  5. public class StringDemo {
  6.     public static void changeString(String tmp) {
  7.         //此处操作具有一定的迷惑行为, 通常情况下只有基本数据类型才会这么操作;
  8.         //但是对与String类型, 相当于新建了一个对象或者是拿到了常量池中的对象;
  9.         tmp = "new";
  10.         //打印通过函数传递进来的tmp参数的地址
  11.         System.out.println(System.identityHashCode(tmp));
  12.     }
  13.     public static void changeInteger(Integer tmp) {
  14.         //此处操作和String类型一样
  15.         tmp = 199;
  16.         //打印通过函数传递进来的tmp参数的地址
  17.         System.out.println(System.identityHashCode(tmp));
  18.     }
  19.     public static void changeOther(StringDemo stringDemo) {
  20.         System.out.println(System.identityHashCode(stringDemo));
  21.     }
  22.     public static void main(String[] args) {
  23.         String tmp = "old";
  24.         //打印原始的tmp
  25.         System.out.println(tmp);      
  26.         //打印原始的tmp对象地址
  27.         System.out.println(System.identityHashCode(tmp));
  28.         changeString(tmp);
  29.         //打印函数调用后的tmp值
  30.         System.out.println(tmp);
  31.         //出于好奇也测试了一下Integer类型
  32.         Integer iTmp = 1;
  33.         //打印原始的iTmp的值
  34.         System.out.println(iTmp);
  35.         //打印原始的iTmp对象地址
  36.         System.out.println(System.identityHashCode(iTmp));
  37.         changeInteger(iTmp);
  38.         //打印函数调用后iTmp的值
  39.         System.out.println(iTmp);
  40.         //对于普通的java对象
  41.         StringDemo stringDemo = new StringDemo();
  42.         //打印当前对象的地址
  43.         System.out.println(System.identityHashCode(stringDemo));
  44.         changeOther(stringDemo);
  45.     }
  46. }
  47. //执行结果
  48. old
  49. 685325104
  50. 685325104
  51. 460141958
  52. old
  53. 1
  54. 1163157884
  55. 1163157884
  56. 1956725890
  57. 1
  58. 356573597
  59. 356573597
复制代码
以上测试结果得到的结果分析

  1. Integer a;
  2. //此处实际上是java的自动装箱, 相当于调用了valueOf函数
  3. // 实际上是new了一个Integer对象出来,或者将另一个Integer对象直接赋值(可以去看一下Integer的源码)
  4. a = 123;
  5. //基础类型的直接赋值
  6. int b;
  7. b = 123;
  8. //与Integer类似,String类型也有常量池, 相当于缓存, 此处不是重点;
  9. // 相当于new了一个对象出来, 或将另一个String对象直接赋值;
  10. String c;
  11. c = "abc"
复制代码
普通对象操作对比
  1. /**
  2. * @author liwangcai E-mail:1252376504@qq.com
  3. */
  4. public class StringTest {
  5.     public static void changeUser(User user) {
  6.         user = new User("zhang san", 24);
  7.     }
  8.     public static void main(String[] args) {
  9.         User user = new User("li si", 25);
  10.         System.out.println(user);
  11.         changeUser(user);
  12.         System.out.println(user);
  13.     }
  14.     @Data
  15.     @AllArgsConstructor
  16.     @ToString
  17.     static class User {
  18.         private String name;
  19.         private Integer age;
  20.         
  21.     }
  22. }
  23. //执行结果, 可以发现对象的值并没有改变
  24. StringTest.User(name=li si, age=25)
  25. StringTest.User(name=li si, age=25)
  26. Process finished with exit code 0
复制代码
为什么new一个对象并不会改对象值?

如果想要改变String的值正确的操作姿势?

如果要改变String的值应该怎么做?

  1. /**
  2. * @author liwangcai E-mail:1252376504@qq.com
  3. */
  4. public class MyStringTest {
  5.     public static void main(String[] args) {
  6.         MyString myString = new MyString(new char[]{'a', 'b'});
  7.         System.out.println(myString);
  8.         changeMyString(myString);
  9.         System.out.println(myString);
  10.     }
  11.     private static void changeMyString(MyString myString) {
  12.         myString.setValue(new char[]{'c', 'd'});
  13.     }
  14.     @ToString
  15.     @AllArgsConstructor
  16.     @Data
  17.     static class MyString {
  18.         char[] value;
  19.     }
  20. }
  21. //测试结果
  22. //可以发现值改变了
  23. MyStringTest.MyString(value=[a, b])
  24. MyStringTest.MyString(value=[c, d])
  25. Process finished with exit code 0
复制代码
总结


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4