Java Final arraylist

我的问题是将arraylist宣布为final。 我知道,一旦我写完最终的ArrayList list = new ArrayList(); 我可以添加,删除此列表中的对象,但我不能list = new ArrayList()list = list1 。 但是使用声明arraylist作为Private static final ArrayList list = new ArrayList(); 。 除了我上面提到的不同之外,以下两个声明之间的区别是什么:

 1. ArrayList list = new ArrayList() 2. private static final ArrayList list = new ArrayList(); 

你是正确的,声明list最终意味着你不能将list变量重新分配给另一个对象。

另一个问题(我认为)是

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

VS

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

让我们依次拿出每个修饰符。

private只有这个类( SomeClass )可以访问list

static表示要分配的所有SomeClass实例只有一个list变量实例。 列表实例与SomeClass类相关联,而不是与每个新的SomeClass实例相关联。 如果变量是非静态的,则称其为实例变量

final你知道意味着你不能将列表变量重新分配给另一个值。

在第二个声明中没有修饰符,因此变量是一个实例变量,它还获得包私有访问保护(有时称为默认访问保护)。 这意味着这个类( SomeClass )和同一个包中的其他类可以访问该变量。

您可以在此处找到有关publicprivatepackage-private信息: 访问控制

您可以在此处找到有关finalstatic更多信息: 类变量

只是为了“为你的工厂带来一点水”,当你想要使你的名单公开可用但不可修改时,你会理解final的兴趣。

在java中,可以使用Collections.unmodifiableList(modifiableList)使列表不可修改 。

现在看看以下代码:

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

好吧,在任何类中,代码中的任何地方都可以执行类似的操作

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

final关键字添加到变量时,不允许使用前两个关键字

 public static final List MY_PUBLIC_LIST; 

但是你仍然可以修改列表的内容:

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

通过在静态块的末尾添加Collections.unmodifiableList(modifiableList) ,您也可以防止这种情况:

 MY_PUBLIC_LIST = Collections.unmodifiableList(tmp); 

好的,我们差不多了。 只是为了确保你得到整个图片让我们保留Collections.unmodifiableList(modifiableList),但让我删除最终修饰符

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

在那种情况下你能做什么?

那么你可以在第一种情况下做你想做的任何事情(假设你先分配新列表):

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

当你说

 final ArrayList list = new ArrayList(); 

这意味着变量list将始终指向同一个ArrayList对象。 有两种情况可以使用它。

  1. 您希望确保在收到其值后,没有人重新分配您的list变量。 这可以降低复杂性并有助于理解类/方法的语义。 在这种情况下,通常使用良好的命名约定和减少方法长度会更好(类/方法已经过于复杂而不易理解)。
  2. 使用内部类时 ,需要在封闭范围内将变量声明为final ,以便可以在内部类中访问它们。 这样,Java可以将你的final变量复制到内部类对象中(它永远不会改变它的值),并且内部类对象不需要担心外部类对象发生什么,而内部类对象是活着的并且需要访问该变量的值。

问题的第二部分是关于两者之间的区别

 ArrayList list = new ArrayList(); 

 private static final ArrayList list = new ArrayList(); 

当然,差异在于修饰符。 private意味着在类外部不可见, static意味着它在类级别定义并且不需要存在实例,并且上面讨论了final 。 没有修饰符意味着包私有或默认访问 。

你说“我可以添加,删除(和查找)对象”,但是谁?

您的两个案例之间的差异涉及可以调用这些列表操作的代码。

通常,您需要考虑声明的范围,如果降低变量的可见性,则会大大提高代码的可维护性。 如果你有一个class级:

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

在应用程序的任何其他位置,任何其他代码都可以更改该重要值。 相反,如果您将其设为私有并提供读取访问器:

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

你现在知道只有类本身可以改变它 – 对于大型应用程序,这大大提高了可维护性。 因此声明列表私有限制了代码可以看到的内容,并更改列表的内容。

static的使用使得列表的所有实例共享列表,而不是每个实例获得其ovn副本。