とても厄介な質問があります...
void changeString(String str){
str = "Hello world":
}
main(){
String myStr = new String("");
changeString(myStr);
}
main
が返されても、値は""
ではなく"Hello world"
。何故ですか?
また、どのように機能させるのですか?関数changeString
で取得した文字列を「Hello world」に変更するとします。
なぜそれが機能しないのか誰もが説明しましたが、それを機能させる方法を誰も説明しませんでした。あなたの最も簡単なオプションは使用することです:
_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メソッドでは、すべてが値で渡されます。これには参照が含まれます。これは、次の2つの異なるメソッドで説明できます。
_void doNothing(Thing obj) {
obj = new Something();
}
void doSomething(Thing obj) {
obj.changeMe();
}
_
doNothing(obj)
からmain()
を呼び出す場合(またはそのことについてはどこでも)、obj
は呼び出し先で変更されません。これは、doNothing
が新しいThing
を作成し、その新しい参照をobj
に割り当てるためです- メソッドのスコープ内。
一方、doSomething
ではobj.changeMe()
を呼び出しており、値によって渡されたobj
を逆参照して変更します。
Javaは、呼び出しを評価するために 値による呼び出し 戦略を使用します。
つまり、値はstr
にコピーされるため、str
に割り当てても、元の値は変更されません。
String
の変更が頻繁に発生する場合は、StringBuffer
またはStringBuilder
を変数に割り当て、その内容を変更して、必要な場合にのみString
に変換することもできます。
少し拡張 NullUserExceptionの優れた答え 、より一般的な解決策は次のとおりです。
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);
}
}
参照myStr
は値によって関数changeString
に渡され、変更は呼び出し元の関数に反映されないためです。
PS:私はJava男ではありません。
ビル、私はリストを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!」と表示されます。
これが他の人にも役立つことを願っています!
-ポート転送ポッドキャスト