Управление последней переменной в Java

Если вы знаете точную позицию, будет работать исключение из всех следующих братьев :nth-child().

ul li:not(:nth-child(n+3))

Что бы выбрать все li s до третьего (например, 1-го и 2-го) , Но, по-моему, это выглядит уродливым и очень плотным.

Вы также можете выбрать n-й-правый справа налево:

ul li:nth-child(-n+2)

Что делает то же самое .

45
задан Dusk 8 August 2009 в 21:14
поделиться

8 ответов

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

final StringBuffer s = new StringBuffer();

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

s.append("something");

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

s = null;

или

s = anotherBuffer;

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

final String s = "";

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

99
ответ дан 26 November 2019 в 20:58
поделиться

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

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

public static void setValueOnField(Object instance, Field field, Object value)
        throws NoSuchFieldException, IOException, IllegalArgumentException,
        IllegalAccessException {
    try (Accessor<Field> access = open(field)) {
        field.set(instance, value);
    }
}


  public static class Accessor<T extends AccessibleObject & Member>
            implements Closeable {
        private final boolean isAccessible;
        private final boolean isFinal;
        private final int modifiers;
        private final T accessibleObject;

        private Accessor(T accessibleObject) throws IOException {
            super();
            if (accessibleObject == null) {
                throw new IOException(
                        "Error preparing field for accesibility: Field is null");
            }
            try {
                this.accessibleObject = accessibleObject;
                this.modifiers = accessibleObject.getModifiers();
                this.isAccessible = accessibleObject.isAccessible();
                this.isFinal = Modifier.isFinal(modifiers);
                if (!this.isAccessible) {
                    accessibleObject.setAccessible(true);
                }
                if (this.isFinal) {
                    getModifiersField(accessibleObject).setInt(
                            accessibleObject, modifiers & ~Modifier.FINAL);
                }
            } catch (Exception e) {
                throw new IOException("Error preparing field for accesibility",
                        e);
            }

        }

        @Override
        public void close() throws IOException {

            if (!this.isAccessible) {
                accessibleObject.setAccessible(false);
            }
            if (this.isFinal) {
                try {
                    getModifiersField(accessibleObject).setInt(
                            accessibleObject, modifiers);
                } catch (Exception e) {
                    throw new IOException("Error setting field to final", e);
                }
            }
        }

        public T getAccessibleObject() {
            return accessibleObject;
        }

        private static Field getModifiersField(AccessibleObject toFetch) {
            Field field;
            try {
                field = toFetch.getClass().getField("modifiers");
                field.setAccessible(true);
                return field;
            } catch (Exception e) {
                throw new RuntimeException(
                        "Error occured getting modifiers field", e);
            }
        }
    }
0
ответ дан 26 November 2019 в 20:58
поделиться

Если у вас есть последняя ссылка на объект 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;
    }
}

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

17
ответ дан 26 November 2019 в 20:58
поделиться

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

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

4
ответ дан 26 November 2019 в 20:58
поделиться

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

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

3
ответ дан 26 November 2019 в 20:58
поделиться

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

-2
ответ дан 26 November 2019 в 20:58
поделиться

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

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

0
ответ дан 26 November 2019 в 20:58
поделиться

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

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

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

0
ответ дан 26 November 2019 в 20:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: