Изменение неизменяемого объекта в классе [дубликат]

Вы используете массив как объект, разница между getElementbyId и getElementsByClassName такова:

  • getElementbyId вернет вам объект.
  • getElementsByClassName вернет вам массив.

getElementsByClassName

Метод getElementsByClassName(classNames) принимает строку, содержащую неупорядоченный набор уникальных разделенных пробелами маркеры, представляющие классы. При вызове метод должен возвращать живой объект NodeList, содержащий все элементы документа, которые имеют все классы, указанные в этом аргументе, получив классы, разделив строку на пробелы. Если в аргументе нет токенов, тогда метод должен возвращать пустой NodeList.

blockquote>

https://www.w3.org/TR/2008/WD-html5 -20080610 / dom.html # getelementsbyclassname

getElementById

Метод getElementById () обращается к первому элементу с указанным id.

blockquote>

http://www.w3schools.com/jsref/met_doc_getelementbyid.asp

в вашем коде строки:

1- document.getElementsByClassName ('myElement'). Style.size = '100px';

blockquote>

НЕ будет работать, как ожидалось, потому что getElementByClassName вернет массив, и массив будет НЕ имеет свойство style, вы будете обращаться к каждому element, итерации их.

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

59
задан MyTitle 25 May 2012 в 09:08
поделиться

12 ответов

Но что делает эффект окончательным?

Это означает, что вы не можете переустановить переменную, чтобы указать на другой экземпляр коллекции :

final List<Integer> list = new ArrayList<Integer>();
list = new ArrayList<Integer>(); // Since `list' is final, this won't compile

В качестве стиля я объявляю большинство ссылок, которые я не намерен изменять как final.

Я все еще могу добавить в ArrayList новые элементы, удалите элементы и обновите их.

Если вы хотите, вы можете предотвратить вставку, удаление и т. д. с помощью Collections.unmodifiableList() :

final List<Integer> list = Collections.unmodifiableList(new ArrayList<Integer>(...));
113
ответ дан NPE 21 August 2018 в 16:02
поделиться
  • 1
    +1 Использование конечных полей может улучшить ясность, поскольку классы могут быть довольно длинными. Я не использую final в методах, так как стараюсь разбить длинные методы. – Peter Lawrey 25 May 2012 в 09:19

Это просто означает, что вы не можете повторно назначить свою ссылку. Попытка сделать что-то вроде приведенного ниже приведет к ошибке компилятора.

final List<String> list = new ArrayList<String>();

list = new LinkedList<String>();
     ^
     Compiler error here

Если вам действительно нужен неизменный список, вы должны использовать метод Collections.unmodifiableList().

14
ответ дан adarshr 21 August 2018 в 16:02
поделиться

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

Если вы хотите, чтобы конечный (неизменный) ArrayList перешел к утилитарному методу класса Collections.unmodifaibleList (список).

0
ответ дан Adwivedi 21 August 2018 в 16:02
поделиться

Я лично отмечаю поле коллекций моих классов как final, чтобы сохранить пользователей моего класса от проверки, является ли он нулевым или нет. Это работает, потому что, как только значение уже назначено конечной переменной, оно никогда не может быть переназначено другому значению, включая null.

1
ответ дан Cody Gray 21 August 2018 в 16:02
поделиться

Вы не можете переустановить его в другую коллекцию, как сказал aix.

Пример: В сочетании с неизмененной реализацией списка вы получаете безопасные члены, которые вы можете сделать общедоступными.

Пример: Когда вы полагаетесь на эту ссылку, она не меняется, вам нужно финал. Это верно, например, в сценариях синхронизации.

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

1
ответ дан Fabian Barney 21 August 2018 в 16:02
поделиться

final имеет много последствий при многопоточности.

  1. JMM четко определяет, что завершение инициализации поля final гарантировано.

Что не ясно определено:

  1. Компиляторы могут свободно переупорядочивать их по барьерам памяти.
  2. Компиляторы всегда могут читать кешированную копию.
4
ответ дан Lauren 21 August 2018 в 16:02
поделиться

Финал - это ключевое слово или зарезервированное слово в java и может применяться к переменным-членам, методам, классам и локальным переменным в Java. После того, как вы сделаете контрольный финал, вам не удастся изменить эту ссылку, и компилятор проверит это и поднимет ошибку компиляции, если вы попытаетесь повторно инициализировать конечные переменные в java.

1
ответ дан lfergon 21 August 2018 в 16:02
поделиться

Вы не сможете изменить свою ссылку, используя new ArrayList, например.

8
ответ дан Michael Laffargue 21 August 2018 в 16:02
поделиться

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

Но создание переменной final имеет другие преимущества:

  • Это предотвращает изменение переменной, если она будет оставаться постоянной. Это может помочь предотвратить будущие ошибки.
  • Создание переменных final может помочь компилятору выполнить определенные оптимизации производительности.

В целом, чем больше вещей вы делаете неизменяемыми, лучше. Поэтому окончание ссылок (даже если они являются ссылками на изменяемые объекты), как правило, является хорошей идеей.

3
ответ дан mikera 21 August 2018 в 16:02
поделиться

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

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

Вот неизменный класс с неизменным объявлением List:

public final class ImmutableClassWithArrayList {
 final List<String> theFinalListVar = new ArrayList<String>();
}

И вот драйвер:

public class ImmutableClassWithArrayListTester {
public static void main(String[] args) {
    ImmutableClassWithArrayList immClass = new ImmutableClassWithArrayList();
    immClass.theFinalListVar.add("name");
    immClass.theFinalListVar.forEach(str -> System.out.println(str));
 }
}

Как вы можете видеть, основным методом является добавление (изменение) списка. Так что единственное, что нужно отметить, это то, что «ссылка» на объект типа коллекции не может быть переназначена другому такому объекту. Как и в ответе adarshr выше, вы не можете сделать immClass.theFinalListVar = new ArrayList (); в основном методе здесь.

Часть модификации действительно помогла мне разобраться в этом и надеюсь, что она помогает таким же образом.

0
ответ дан Nirmal 21 August 2018 в 16:02
поделиться

Чтобы получить действительно неизменный список, вам нужно будет сделать глубокие копии содержимого списка. UnmodifiableList будет только отображать список ссылок несколько неизменным. Теперь создание глубокой копии списка или массива будет жестким по памяти с ростом размера. Вы можете использовать сериализацию / десериализацию и хранить глубокую копию массива / списка во временном файле. Установщик не будет доступен, так как элемент varaible должен быть неизменным. Геттер будет сериализовать переменную-член в файл, а затем десализировать ее, чтобы получить глубокую копию. Серализация имеет врожденный характер проникновения в глубины дерева объектов. Это обеспечило бы полную неизменность при некоторых эксплуатационных расходах.

 package com.home.immutable.serial;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;

public final class ImmutableBySerial {

    private final int num;
    private final String str;
    private final ArrayList<TestObjSerial> immutableList;

    ImmutableBySerial(int num, String str, ArrayList<TestObjSerial> list){
        this.num = num;
        this.str = str;
        this.immutableList = getDeepCloned(list);
    }

    public int getNum(){
        return num;
    }

    public String getStr(){
        return str;
    }

    public ArrayList<TestObjSerial> getImmutableList(){
        return getDeepCloned(immutableList);
    }

    private ArrayList<TestObjSerial> getDeepCloned(ArrayList<TestObjSerial> list){
        FileOutputStream fos = null;
        ObjectOutputStream oos = null;
        FileInputStream fis = null;
        ObjectInputStream ois = null;
        ArrayList<TestObjSerial> clonedObj = null;
        try {
             fos = new FileOutputStream(new File("temp"));
             oos = new ObjectOutputStream(fos);
             oos.writeObject(list);
             fis = new FileInputStream(new File("temp"));
             ois = new ObjectInputStream(fis);
             clonedObj = (ArrayList<TestObjSerial>)ois.readObject();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                oos.close();
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return clonedObj;
    }
}
1
ответ дан Rajeev Ranjan 21 August 2018 в 16:02
поделиться

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

Если вы комбинируете ключевое слово final с помощью Collections.unmodifiableList , вы выполняете поведение вероятно, пытается достичь, например:

final List fixedList = Collections.unmodifiableList(someList);

Это приводит к тому, что список, на который указывает fixedList, не может быть изменен. Остерегайтесь, однако, что это все равно может быть изменено с помощью ссылки someList (поэтому убедитесь, что после этой привязки он выходит за пределы области.)

5
ответ дан rsp 21 August 2018 в 16:02
поделиться
Другие вопросы по тегам:

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