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
)和同一个包中的其他类可以访问该变量。
您可以在此处找到有关public
, private
和package-private
信息: 访问控制
您可以在此处找到有关final
和static
更多信息: 类变量
只是为了“为你的工厂带来一点水”,当你想要使你的名单公开可用但不可修改时,你会理解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
对象。 有两种情况可以使用它。
- 您希望确保在收到其值后,没有人重新分配您的
list
变量。 这可以降低复杂性并有助于理解类/方法的语义。 在这种情况下,通常使用良好的命名约定和减少方法长度会更好(类/方法已经过于复杂而不易理解)。 - 使用内部类时 ,需要在封闭范围内将变量声明为
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副本。