Изменение значения строки строки в строке
У меня есть этот очень неудобный вопрос...
void changeString(String str){
str = "Hello world":
}
main(){
String myStr = new String("");
changeString(myStr);
}
Когда возвращается main
, значение все равно ""
, а не "Hello world"
. Почему это?
Кроме того, как мне заставить его работать? Скажем, я хочу, чтобы моя функция changeString
изменила строку, полученную в "Hello world".
Ответы
Ответ 1
Все объяснили, почему это не работает, но никто не объяснил, как заставить его работать. Самый простой способ - использовать:
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()
, а эти dereferences obj
- который был передан по значению - и меняет его.
Ответ 2
Java использует вызов по значению startegy для оценки вызовов.
То есть, значение копируется в str
, поэтому, если вы назначаете str
, который не меняет исходное значение.
Ответ 3
Если изменение вашего String
происходит очень часто, вы также можете назначить переменную StringBuffer
или StringBuilder
вашей переменной и изменить ее содержимое и преобразовать ее только в String
, когда это необходимо.
Ответ 4
Развернуть бит на отличный ответ 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);
}
}
Ответ 5
Поскольку ссылка myStr
передается по значению функции changeString
, и это изменение не возвращается обратно к вызывающей функции.
P.S: Я не парень Java.
Ответ 6
Bill, у меня есть решение вашей проблемы, которая использует 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!"
Я надеюсь, что это тоже поможет другим!
-Портальный подкаст