【发布时间】:2021-01-21 17:46:36
【问题描述】:
我正在编写一个处理字符串的方法(以提取某些内容):public static String myProcessor (String myInput) {...
我想在这个方法中有一些 String 对象,我可以在 (workString = workString.replace(...) 上应用我的转换
但是,我不想更改原始字符串(通过对我的方法的引用,即:myProcessor(originalString)) - 因为在我的方法被调用后可能会有方法调用,这也想要在我的方法调用之前处理/提取 原始字符串中的某些内容
我仍在学习 Java,根据我的书(Deitel & Deitel - “Java How To Program”):
〜“原始类型是按值传递的。其他变量类型用于对象,它们是按引用传递的,因此对象的变量赋值是将引用传递给同一对象。一个变量引用的对象发生变化读取其他变量时可以看到(如果Object var2 = var1)"
(这不是逐字逐句,只是我从中理解的!)
所以,我想我会尝试:String workString = new String(myInput);,这应该使用来自 myInput 的数据创建一个新的 String 对象,但我可以随意操作 workString,而不必担心我正在对在别处使用的对象。
IntelliJ 建议这是多余的,我可以这样做:String workString = myInput,这让我很困惑......
IntelliJ 就在这里吗?
实际上,我什至需要创建一个本地范围workString,或者一旦变量“到达”到方法中,引用就会“分离”? (即:在myProcessor 内部,myInput 不再持有来自对myProcessor 的调用对originalString 的引用,而是创建了一个新的String 对象?
如果您的答案仅涉及字符串对象或所有对象,您能否也请简要提及一下?
我有一种感觉,也许 String 介于 Primitive 类型和 Object 类型之间,并且应用了特殊规则......
【问题讨论】:
-
在 Java 中,一切都是按值传递的:stackoverflow.com/questions/40480/…
-
此外,
String是不可变的,因此复制它很少有任何收获。您对workString所做的任何操作都不会更改原始字符串,它会创建一个新字符串。 -
@DraxDomax 没有改变字符串,它正在创建一个新字符串并重新分配变量。
-
当您执行
myString = myString.replace("x","y")时,您正在创建一个如上所述的 new 字符串,并将 myString 持有的引用替换为对该新字符串的引用;原始字符串不变。myProcessor(originalString)的调用者仍然看到对他们传递的原始 String 对象的原始引用,因此不受任何影响。 -
我建议阅读@MAnouti 在第一条评论中的链接。在 Java 中,一切都是按值传递。这包括对象和原语。关于对象的细微差别在于传递的“值”是对对象的引用。这就是为什么如果你将
List传递给一个方法,向它添加一个元素,然后在方法的调用者中查询列表,你会看到变化;您已经修改了对象本身。但是,如果同样的方法执行list = new ArrayList<>();(其中list是参数),则根本不会影响方法的调用者。
标签: java string object pass-by-reference pass-by-value