Declaring a List field with the final keyword
Asked Answered
P

7

40

If I have the following statement within a class where Synapse is an abstract type:

private final List<Synapse> synapses;

Does final allow me to still be able to change the state of the Synapse objects in the List, but prevent me from adding new Synapse objects to the list? If I am wrong, could you please explain what final is doing and when I should be using the keyword final instead.

Pinworm answered 26/10, 2012 at 0:47 Comment(0)
F
72

No, the final keyword does not make the list, or its contents immutable. If you want an immutable List, you should use:

List<Synapse> unmodifiableList = Collections.unmodifiableList(synapses);

What the final keyword does is prevent you from assigning a new value to the 'synapses' variable. I.e., you cannot write:

final List<Synapse> synapses = createList();
synapses = createNewList();

You can, however, write:

List<Synapse> synapses = createList();
synapses = createNewList();

In essense, you can still change, add and remove the contents of the list, but cannot create a new list assigned to the variable synapses.

Forceful answered 26/10, 2012 at 0:52 Comment(3)
It's worth pointing out that although nothing can be added, removed, or replaced in unmodifiableList constructed like this, the elements of the list can still have their state changed (if they are mutable). Nothing about the list declaration or construction can prevent that.Friedrick
So you could do: final List<Synapse> synapses = createList(); and then do synapses.add(newSynapse())? Then it means synapses can't point to anything else but this list right?Mainmast
@A.Vieira yes, right, as long as synapses is a mutable object like ArrayList.Equestrian
E
9

final prevents you from reassigning synapses after you've assigned it once - you can still add/remove elements as you would normally. You can read more about the final keyword here.

Eleusis answered 26/10, 2012 at 0:49 Comment(0)
N
6

You can still change, add and remove the contents of the list, but cannot create a new list assigned to the variable.

Nickienicklaus answered 26/10, 2012 at 0:50 Comment(0)
M
3

The Java Language Specification writes:

A variable can be declared final. A final variable may only be assigned to once. Declaring a variable final can serve as useful documentation that its value will not change and can help avoid programming errors.

It is a compile-time error if a final variable is assigned to unless it is definitely unassigned (§16) immediately prior to the assignment.

A blank final is a final variable whose declaration lacks an initializer.

Once a final variable has been assigned, it always contains the same value. If a final variable holds a reference to an object, then the state of the object may be changed by operations on the object, but the variable will always refer to the same object.

Therefore, if you wish to enforce that the state reachable through the variable does not change, you have to declare the variable final, use an unmodifiable List (for instance with Collections.unmodifiableList), and make Synapse objects immutable.

Maun answered 26/10, 2012 at 0:53 Comment(0)
V
1

The final implementation implies that object reference once initiated, the reference itself can never be changed but the content can of course be. Its not violating the rules at all. You have specified only one rule about the reference change which is working accordingly. If you want the values should also never change you should go for immutable lists i.e

List<String> items = Collections.unmodifiableList(Arrays.asList("a", "b", "c"));

See the following related question.

Vernacularism answered 26/10, 2012 at 0:54 Comment(0)
I
0

Above answer explained all in theory here you can find code to run and see actual diffrence ,advisable to use loacal variable

package exp_test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class testList {
    final static List<String> synapses = new ArrayList();;

    public static void main(String[] args) {

        synapses.add("A");
        System.out.println(synapses);
        //
        System.out.println(finalLisTest(synapses));
        //
        System.out.println(synapses);
        //
        synapses.add("B");

        List<String> unmodifiableList = Collections.unmodifiableList(synapses);
        System.out.println(finalLisTest(unmodifiableList));
        //
        System.out.println(unmodifiableList);

    }

    private static List finalLisTest(List<String> list) {
        list.remove(0);
        return null;

    }

}

Results :

[A]
null
[]
Exception in thread "main" java.lang.UnsupportedOperationException
    at java.util.Collections$UnmodifiableList.remove(Collections.java:1317)
    at exp_test.testList.finalLisTest(testList.java:29)
    at exp_test.testList.main(testList.java:22)
Itinerancy answered 25/10, 2019 at 15:56 Comment(0)
E
0

A List with final keyword, still you can add as well as remove. But you cannot copy the list into another list.

Elegy answered 16/6, 2022 at 15:59 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Chetchetah

© 2022 - 2024 — McMap. All rights reserved.