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

Конечная манипуляция переменной в Java

Может кто-нибудь, пожалуйста, скажите мне, что означает следующая строка в контексте Java:

конечная переменная все еще может быть манипулировать, если это не будет неизменным

Насколько я знаю, объявив какую-либо переменную окончательной, вы не можете изменить ее снова, а затем что означают слова неизменяемые в приведенной выше строке?

4b9b3361

Ответ 1

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

final StringBuffer s = new StringBuffer();

Содержимое StringBuffer все равно может быть изменено произвольно:

s.append("something");

Но вы не можете сказать:

s = null;

или

s = anotherBuffer;

С другой стороны:

final String s = "";

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

Ответ 2

Если у вас есть окончательная ссылка на объект Java, вы все равно можете манипулировать им, но не можете изменить его ссылку. Например, этот код совершенно легален:

import javax.swing.JLabel;

class Test1 {
    private final static JLabel l = new JLabel("Old text");
    public static void main(String[] args) {
        System.err.println(l.getText());
        l.setText("New Text");
        System.err.println(l.getText());
    }
}

Но вы не можете сказать:

l = new JLabel("Newest Text");

После первого присвоения l. Обратите внимание, что вы можете сделать это, хотя:

import javax.swing.JLabel;

class Test1 {
    public static void main(String[] args) {
        final JLabel l;
        String s = getArbitaryString(); // Assume this method returns a string
        l = new JLabel(s);
        System.err.println(l.getText());
    }
}

Это можно сделать, потому что когда l объявлено, он не присваивается ничему, даже не равному null. Таким образом, вам разрешено присваивать ему что-то только один раз.

То же самое касается примитивов. Вы можете присвоить ему значение следующим образом:

class Test1 {
    public static void main(String[] args) {
        final int i;
        i = 2;
    }
}

Но теперь вы не можете манипулировать им дальше, поскольку единственное, что вы можете сделать для примитивных типов, - это присвоить им значения.

Ответ 3

Вы не можете изменить, к какому объекту или ценности относится конечная переменная. Вы можете назначить только конечную переменную один раз.

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

Ответ 4

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

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

Ответ 5

Вы можете вызвать любой метод на нем, даже если метод может изменить состояние объекта, на который указывает ссылка. Например

final MyClass myClass = new MyClass();
myClass.setVar(something);

Это прекрасно, потому что сам myClass не меняется, т.е. вы не выполняете myClass = myClass1;.

Ответ 6

Тот, который всегда убивает меня?

Если вы хотите, чтобы конечные переменные действительно были такими же безопасными, как вы думали, вам нужно много дополнительного кода, чтобы вернуть копию строки [].

Ответ 7

Вы можете манипулировать изменяемыми конечными переменными, например. типа StringBuffer, но вы не можете манипулировать конечными переменными неизменяемых типов.

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

Ответ 8

Да окончательная переменная может быть изменена.

    final StringBuffer s = new StringBuffer();
    // won't work
    s = new StringBuffer();
    //this works
    s.append("hai");

Вы не можете изменить ссылку, но можно изменить поля объекта. для более подробной информации

Ответ 9

Вы все равно можете изменить "конечную" переменную с помощью Reflection.