Подтвердить что ты не робот

Могу ли я изменить значение объекта String, переданное моему методу?

Я нашел следующий вопрос Является ли Java "pass-by-reference" " или "проход по значению" .

Я прочитал почти все, но не смог узнать, что делать, если мне нужен метод foo(-), чтобы изменить значение String ? (может быть, это тоже не ссылка), это не имеет значения для меня).

void foo(String errorText){ 
    errorText="bla bla";
}

int main(){ 
    String error="initial"; 
    foo(error); 
    System.out.println(error);
}

Я хочу видеть bla bla на консоли. Возможно ли это?

4b9b3361

Ответ 1

Вы не можете изменить значение errorText в foo, поскольку этот метод в настоящее время объявлен. Даже если вы передаете ссылку String errorText в foo, Java String неизменяемы - вы не можете их изменить.

Однако вы можете использовать StringBuffer (или StringBuilder). Эти классы могут быть отредактированы в вашем методе foo.

public class Test {
    public static void foo(StringBuilder errorText){ 
        errorText.delete(0, errorText.length());
        errorText.append("bla bla");
    }

    public static void main(String[] args) { 
        StringBuilder error=new StringBuilder("initial");
        foo(error); 
        System.out.println(error);
    }
}

Другие решения - использовать класс-оболочку (создать класс для хранения ссылки на String и изменить ссылку в foo) или просто вернуть строку.

Ответ 2

Использовать возвращаемое значение метода или создать класс-оболочку.

Вернуть ли это значение:

String foo(String errorText){ 
    return "bla bla";
}

int main(){ 
    String error="initial"; 
    error = foo(error); 
    System.out.println(error);
}

Оберните значение в объект:

class StringWrapper {
    private String string;
    public StringWrapper(String s) {
        this.string = s;
    }
    public String getString() {
        return this.string;
    }
    public void setString(String s) {
        this.string = s;
    }
}

void foo(StringWrapper errorText){ 
    errorText.setString("bla bla");
}

int main(){ 
    StringWrapper error=new StringWrapper("initial"); 
    foo(error); 
    System.out.println(error.getString());
}

Ответ 3

Да, вы можете изменить это с помощью отражений, но против правила.

void foo(String errorText) {
    try {
        final Class<String> type = String.class;
        final java.lang.reflect.Field valueField = type.getDeclaredField("value");
        valueField.setAccessible(true);
        valueField.set(errorText, "bla bla".toCharArray());
    } catch (Exception e) {
    }

}

public static void main(String[] args) {
    String error = new String("initial");
    foo(error);
    System.out.println(error);
}

Ответ 4

Значения String неизменяемы - поэтому, как только вы получите значение, вы застряли с ним.

Ответ 5

Literal String обрабатываются специально языком Java; ваш код примерно эквивалентен:

void foo(String errorText){ // at this point, errorText refers to the original string
    errorText=new String("bla bla"); // now it refers to a new string
}

int main(){ 
    String error=new String("initial"); // error is a reference to the original string
    foo(error); // pass a *copy* of the reference
    System.out.println(error);
}

Другими словами, вы просто указываете локальную ссылку errorText на другой объект String, который не влияет ни на что вне метода.

В общем случае String неизменяемы; нет способа изменить их.

Ответ 6

Вы можете переназначить ссылку на String:

String foo(String err) {
  return "bla blah"
}

error = foo(error);