Вы используете массив как объект, разница между getElementbyId
и getElementsByClassName
такова:
getElementbyId
вернет вам объект. getElementsByClassName
вернет вам массив. Метод
blockquote>getElementsByClassName(classNames)
принимает строку, содержащую неупорядоченный набор уникальных разделенных пробелами маркеры, представляющие классы. При вызове метод должен возвращать живой объектNodeList
, содержащий все элементы документа, которые имеют все классы, указанные в этом аргументе, получив классы, разделив строку на пробелы. Если в аргументе нет токенов, тогда метод должен возвращать пустой NodeList.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
.
Но что делает эффект окончательным?
Это означает, что вы не можете переустановить переменную, чтобы указать на другой экземпляр коллекции :
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>(...));
Это просто означает, что вы не можете повторно назначить свою ссылку. Попытка сделать что-то вроде приведенного ниже приведет к ошибке компилятора.
final List<String> list = new ArrayList<String>();
list = new LinkedList<String>();
^
Compiler error here
Если вам действительно нужен неизменный список, вы должны использовать метод Collections.unmodifiableList()
.
По сути, вы пытаетесь достичь здесь, чтобы сделать список неизменным, я думаю. Однако, когда вы помечаете окончательный список ссылок, это означает, что ссылка can not указана на любой другой объект списка, отличный от этого.
Если вы хотите, чтобы конечный (неизменный) ArrayList перешел к утилитарному методу класса Collections.unmodifaibleList (список).
Я лично отмечаю поле коллекций моих классов как final
, чтобы сохранить пользователей моего класса от проверки, является ли он нулевым или нет. Это работает, потому что, как только значение уже назначено конечной переменной, оно никогда не может быть переназначено другому значению, включая null.
Вы не можете переустановить его в другую коллекцию, как сказал aix.
Пример: В сочетании с неизмененной реализацией списка вы получаете безопасные члены, которые вы можете сделать общедоступными.
Пример: Когда вы полагаетесь на эту ссылку, она не меняется, вам нужно финал. Это верно, например, в сценариях синхронизации.
Там может быть гораздо больше примеров. Это хороший стиль, чтобы объявить участников окончательными, если вы вообще не собираетесь изменять ссылку.
final
имеет много последствий при многопоточности.
final
гарантировано. Что не ясно определено:
Финал - это ключевое слово или зарезервированное слово в java и может применяться к переменным-членам, методам, классам и локальным переменным в Java. После того, как вы сделаете контрольный финал, вам не удастся изменить эту ссылку, и компилятор проверит это и поднимет ошибку компиляции, если вы попытаетесь повторно инициализировать конечные переменные в java.
blockquote>
Вы не сможете изменить свою ссылку, используя new ArrayList
, например.
Это не влияет на то, что вы можете сделать с ArrayList, как вы по праву наблюдаете - сам ArrayList по-прежнему изменен. Вы только что сделали ссылку неизменной.
Но создание переменной final имеет другие преимущества:
final
может помочь компилятору выполнить определенные оптимизации производительности. В целом, чем больше вещей вы делаете неизменяемыми, лучше. Поэтому окончание ссылок (даже если они являются ссылками на изменяемые объекты), как правило, является хорошей идеей.
Я подумал об одном и том же вопросе и закодировал и пример, чтобы добавить к объяснению еще один угол.
Окончательный список элементов массива можно изменить, см. пример ниже и запустить это для себя.
blockquote>Вот неизменный класс с неизменным объявлением 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 (); в основном методе здесь.
blockquote>Часть модификации действительно помогла мне разобраться в этом и надеюсь, что она помогает таким же образом.
Чтобы получить действительно неизменный список, вам нужно будет сделать глубокие копии содержимого списка. 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;
}
}
Выполнение переменной final
гарантирует, что вы не сможете повторно назначить эту ссылку задания после ее назначения. Как вы уже упоминаете, вы все равно можете использовать методы списков для внесения изменений.
Если вы комбинируете ключевое слово final
с помощью Collections.unmodifiableList , вы выполняете поведение вероятно, пытается достичь, например:
final List fixedList = Collections.unmodifiableList(someList);
Это приводит к тому, что список, на который указывает fixedList
, не может быть изменен. Остерегайтесь, однако, что это все равно может быть изменено с помощью ссылки someList
(поэтому убедитесь, что после этой привязки он выходит за пределы области.)