2012-05-02 3 views
0

Это очень упрощенная версия файла класса, над которым я работаю, я только что использовал эти классы, чтобы показать свою проблему.java Строковые переменные не установлены

public class Test { 
    private String string1 = null; 
    private String string2 = null; 

    private void setString(String s) { 
     s = "hello"; 
    } 

    private void set() { 
     setString(string1); 
     setString(string2); 
    } 

    public void print() { 
     System.out.println(string1); 
     System.out.println(string2); 
    } 

    public void initialise() { 
     set(); 
     print(); 
    } 
} 

public class StringTest { 
    public static void main(String[] args) { 
     Test test = new Test(); 
     test.initialise(); 
    } 
} 

В любом случае, в принципе, после этого две строковые переменные по-прежнему равны нулю. Что вызывает эту проблему? и как я могу обойти это? (Все еще изучая основы java - если это актуально).

Любая помощь/руководство очень ценится.

+4

@Lion Это демонстрация OP для этой проблемы. – adarshr

+2

Не нужно быть придурком, но в гораздо большем файле класса требуется нечто подобное. – Ari

+0

@ Андрюс Странный, компилируется для меня отлично. – Ari

ответ

5

Ваша проблема в том, что Java is pass by value, поэтому ваш метод setString ничего не делает. Чтобы изменить значение string1, у вас должно быть string1 = xxxx; где-то в вашем коде. Например:

private void set() { 
    string1 = getDefaultString(); 
    string2 = getDefaultString(); 
} 

private String getDefaultString() { 
    return "hello"; 
} 
6

Поскольку строка является неизменной, любое изменение, которое вы делаете внутри метода, будет локальным для этого метода.

private void setString(String s) { 
    s = "hello"; 
} 

s не может быть изменен.

Я могу представить два варианта.

Вариант 1

Сделать s переменную экземпляра (поле) и изменить свой метод.

открытый класс Test { private Строка string1 = null; private Строка string2 = null; private String s;

private void setString(String s) { 
    this.s = "hello"; 
} 

Вариант 2

проход в StringBuilder/StringBuffer вместо String.

+3

Это объясняет только часть истории; другая часть состоит в том, что '' 'является ссылкой на объект' String' и что * может * быть изменен. –

+0

@OliCharlesworth 's' является * копией * ссылки на объект' String'. Таким образом, даже если вы должны были изменить ссылку путем повторного присвоения, исходная строка не будет изменена (это касается того, что String не была неизменной в первую очередь) – adarshr

0

вы поняли Яву передачи параметров, попробуйте public void setString1(String s) { string1 = s; }

+1

Это было бы немного бессмысленно, как частный метод. –

+0

о, да, метод изменения для публики. – user1335794

-2

уры приложение назначая привет слово в параметре s..but переменной s является типом параметра Thats у отражения воли быть в блоке метода setString() ... не где-либо еще ... использовать переменную экземпляра или статическую переменную, чтобы увидеть отражение присвоения ур.

+5

Пожалуйста, используйте правильный английский, а не «ur» и «y». –

1

Вы устанавливаете значение «s» не String1 или строка2

попробовать что-то подобное.

private void setString(String s) { 
     string1 = "hello"; 
     string2 = "world"; 
    } 
0

Что вы пытаетесь инициализировать значения string1 и string2 к? Две переменные-члены начинаются с null.

Если бы я был лечить Test класс как POJO (обычный старый объект Java), я бы добавить методы геттер/сеттер следующим образом:

public class Test { 

    private String string1; 
    private String string2; 

    public String getString1() { 
    return this.string1; 
    } 

    public String getString2() { 
    return this.string2; 
    } 

    public void setString1(String s) { 
    this.string1 = s; 
    } 

    public void setString2(String s) { 
    this.string2 = s; 
    } 

    /* 
    * Additional methods 
    */ 
    public void set() { 

    setString1("hello"); 
    setString2("world"); 
    } 

    public void print() { 

    System.out.println(this.string1); 
    System.out.println(this.string2); 
    } 

    public void initialize() { 

    set(); 
    print(); 
    } 
} 
+0

В его требовании нет ничего, что указывало бы на необходимость создания сеттеров. Почему вы добавили некоторые? – assylias

+0

Я просто пытался проиллюстрировать обычную практику с POJO в целом. Эти методы не являются частью ответа. –

+1

Я понимаю - я просто указывал, что общий подход должен заключаться в том, чтобы сделать ваши объекты неизменными, насколько это возможно, если вы ** не должны ** сделать их изменчивыми, а не наоборот. – assylias

1

Делая эту Ассигнационного

s = "hello"; 

Уэр создавая новый объект. Он будет иметь другой адрес памяти, чем тот прошел с setString(string1);

Мы должны были бы изменить объект получил на

private void setString(StringBuilder s) { ... } 

вместо создания нового. Нам нужно использовать точно тот же объект, который мы передали в этом методе. Невозможно создать новый, поскольку метод вызывающего не заметил бы (параметры в Java никогда не выводят параметры).

Поскольку строка Java является inmutable, мы не можем изменить ее содержимое: просто создайте новый объект String.

Как указал @adarshr, мы можем использовать StringBuilder или StringBuffer, которые изменяются и изменяют их содержание. Но мы не можем просто заменить StringStringBuilder в вашем коде. Мы должны убедиться, что:

  1. StringBuilder инициализирован перед передачей setString().
  2. StringBuilder не создан снова внутри setString() (мы используем тот же самый, который мы прошли).

Таким образом, заменяя это в коде должно работать:

private StringBuilder string1 = new StringBuilder(); 
private StringBuilder string2 = new StringBuilder(); 

private void setString(StringBuilder s) { 
    s.append("hello"); 
}