Java Final arraylist

前端 未结 4 1357
隐瞒了意图╮
隐瞒了意图╮ 2021-02-05 08:44

My question is regarding declaring an arraylist as final. I know that once I write final ArrayList list = new ArrayList(); I can add, delete objects from this list,

相关标签:
4条回答
  • 2021-02-05 09:24

    You say "I can add, delete (and find) objects", but who is I?

    The different between your two cases concerns from which code those list operations can be called.

    In general you need to consider the scope of the declaration, you greatly increase the maintainability of code if you reduce the visibility of your variables. If you have a class:

    Public Class MyThing {
       public int importantValue;
    
       // more code
    }
    

    That important value can be changed by any other code, anywhere else in an application. If instead you make it private and provide a read accessor:

    Public Class MyThing {
       private int importantValue;
    
       public int getImportantValue(){
           return importantValue;
       }
    
       // more code
    }
    

    you now know only the class itself can change the value - for large applications this massively increases maintainability. So declaring the list private limits what code can see, and change the contents of the list.

    The use of static makes the list shared by all instances of the class, rather than each instance getting its ovn copy.

    0 讨论(0)
  • 2021-02-05 09:30

    Just to "bring a little water to your Mill" you will understand the interest of final when you'll want to make your list publically availiable but unmodifiable.

    In java one can make a list unmodifiable with Collections.unmodifiableList(modifiableList).

    Now have a look to the following code :

    public class MyClass{
      public static List<String> MY_PUBLIC_LIST;
      static{
        ArrayList<String> tmp = new ArrayList<String>();
        tmp.add("a");
        tmp.add("b");
        tmp.add("c");
        MY_PUBLIC_LIST = tmp;
      }
    }
    

    Well, in anyclass, anywhere in your code you can do something like this

    MyClass.MY_PUBLIC_LIST = null;
    MyClass.MY_PUBLIC_LIST = new ArrayList<String>();
    MyClass.MY_PUBLIC_LIST.clear();
    MyClass.MY_PUBLIC_LIST.add("1");
    

    When you add the final keyword to your variable, the first two won't be allowed

    public static final List<String> MY_PUBLIC_LIST;
    

    But you'll still be able to modify the content of the list :

    MyClass.MY_PUBLIC_LIST.clear();
    MyClass.MY_PUBLIC_LIST.add("1");
    

    By adding a Collections.unmodifiableList(modifiableList) at the end of the static block you'll prevent this too :

    MY_PUBLIC_LIST = Collections.unmodifiableList(tmp);
    

    Ok we are almost there. Just to be sure you get the whole picture lets keep the Collections.unmodifiableList(modifiableList) but let me remove the final modifier

    public class MyClass{
      public static List<String> MY_PUBLIC_LIST;
      static{
        ArrayList<String> tmp = new ArrayList<String>();
        tmp.add("a");
        tmp.add("b");
        tmp.add("c");
        MY_PUBLIC_LIST = Collections.unmodifiableList(tmp);
      }
    }
    

    What can you do in that case ?

    ...

    ...

    Well you can do whatever you want like in the first case (given that you assign the new list first) :

    MyClass.MY_PUBLIC_LIST = null;
    MyClass.MY_PUBLIC_LIST = new ArrayList<String>();
    MyClass.MY_PUBLIC_LIST.clear();
    MyClass.MY_PUBLIC_LIST.add("1");
    
    0 讨论(0)
  • 2021-02-05 09:46

    You're right that declaring the list final means that you cannot reassign the list variable to another object.

    The other question (I think) was

    public class SomeClass {
        private static final ArrayList list = new ArrayList();
    }
    

    vs

    public class SomeClass {
        ArrayList list = new ArrayList();
    }
    

    let's take each modifier in turn.

    private Means only this class (SomeClass) can access list

    static Means that there is only one instance of the list variable for all instances of SomeClass to share. The list instance is associated with the SomeClass class rather than each new SomeClass instance. If a variable is non-static it's said to be an instance variable

    final as you know means that you cannot reassign the list variable another value.

    In the second declaration there are no modifiers, so the variable is an instance variable and it also gets package-private access protection (Sometimes called default access protection). This means that this class (SomeClass) and other classes in the same package can access the variable.

    You can find out more about public, private, and package-private here: Access control

    You can find out more about final and static here: Class variables

    0 讨论(0)
  • 2021-02-05 09:46

    When you say

    final ArrayList list = new ArrayList();
    

    this means that the variable list will always point to the same ArrayList object. There are two situations in which this can be useful.

    1. You want to make sure that no-one reassigns your list variable once it has received its value. This can reduce complexity and helps in understanding the semantics of your class/method. In this case you are usually better off by using good naming conventions and reducing method length (the class/method is already too complex to be easily understood).
    2. When using inner classes you need to declare variables as final in an enclosing scope so that you can access them in the inner class. This way, Java can copy your final variable into the inner class object (it will never change its value) and the inner class object does not need to worry what happens to the outer class object while the inner class object is alive and needs to access the value of that variable.

    The second part of your question is about the difference between

    ArrayList list = new ArrayList();
    

    and

    private static final ArrayList list = new ArrayList();
    

    The difference of course are the modifiers. private means not visible outside the class, static means that it is defined on the class level and doesn't need an instance to exist, and final is discussed above. No modifiers means package-private or default access.

    0 讨论(0)
提交回复
热议问题