我有这个非常尴尬的问题......
void changeString(String str){
str = "Hello world":
}
main(){
String myStr = new String("");
changeString(myStr);
}
当main
返回时,该值仍为""
而不是"Hello world"
。那是为什么?
另外,我该如何使它工作?假设我希望我的函数changeString
将其得到的字符串更改为“Hello world”。
答案 0 :(得分:34)
每个人都解释了为什么它不起作用,但没有人解释如何使其发挥作用。最简单的选择是使用:
String changeString() {
return "Hello world";
}
main() {
String myStr = new String("");
myStr = changeString();
}
虽然方法名称在这里用词不当。如果您使用原始想法,则需要以下内容:
void changeString(ChangeableString str) {
str.changeTo("Hello world");
}
main() {
ChangeableString myStr = new ChangeableString("");
changeString(myStr);
}
您的ChangeableString
课程可能是这样的:
class ChangeableString {
String str;
public ChangeableString(String str) {
this.str = str;
}
public void changeTo(String newStr) {
str = newStr;
}
public String toString() {
return str;
}
}
在Java方法中,所有内容都按值传递。这包括参考。这可以通过以下两种不同的方法来说明:
void doNothing(Thing obj) {
obj = new Something();
}
void doSomething(Thing obj) {
obj.changeMe();
}
如果您从doNothing(obj)
(或任何地方)致电main()
,则obj
将不会在被叫方中更改,因为doNothing
会创建新的Thing
并在方法范围中指定对obj
的新引用。
另一方面,在doSomething
中,您正在调用obj.changeMe()
,并取消引用obj
- 按值传递 - 并更改它。
答案 1 :(得分:7)
Java使用call by value策略来评估呼叫。
也就是说,该值会复制到str
,因此如果您指定的str
不会更改原始值。
答案 2 :(得分:3)
如果经常更改String
,您还可以为变量分配StringBuffer
或StringBuilder
并更改其内容,并仅将其转换为String
如果需要的话。
答案 3 :(得分:3)
在NullUserException's excellent answer上扩展一下,这是一个更通用的解决方案:
public class Changeable<T> {
T value;
public Changeable(T value) {
this.value = value;
}
public String toString() {
return value.toString();
}
public boolean equals(Object other) {
if (other instanceof Changeable) {
return value.equals(((Changeable)other).value);
} else {
return value.equals(other);
}
}
public int hashCode() {
return value.hashCode();
}
}
然后可以将Yura的原始代码重写为:
void changeString(Changeable<String> str){
str.value = "Hello world":
}
void main() {
Changeable<String> myStr = new Changeable<String>("");
changeString(myStr);
}
而且,只是为了好玩,这里是Scala:
class Changeable[T](var self: T) extends Proxy;
object Application {
def changeString(str: Changeable[String]): Unit = {
str.self = "Hello world";
}
def main(): Unit = {
val myStr = new Changeable("");
changeString(myStr);
}
}
答案 4 :(得分:1)
因为引用myStr
通过值传递给函数changeString
,并且更改未反映回调用函数。
答案 5 :(得分:0)
比尔,我有一个问题的解决方案,它使用List作为java中的指针!
void changeString(List<String> strPointer ){
String str = "Hello world";
strPointer.add(0, str);
}
main(){
LinkedList<String> list = new LinkedList<String>();
String myStr = new String("");
changeString(list);
myStr = list.get(0);
System.out.println( myStr );
}
这个答案需要一些额外的工作来插入和从列表中取出字符串,但是最后一行将打印“Hello world!”
我希望这也可以帮助别人!
-Port Forward Podcast