所以我有一个名为Album 的类,其中包含一个名为“listOfAllAlbumsCreated”的静态ArrayList。
public class Album {
private static ArrayList<Album> listOfAllAlbumsCreated= new ArrayList<>();
public Album(String albumTitle) {
this.albumTitle = albumTitle;
listOfAllAlbumsCreated.add(this);
}
public static ArrayList<Album> getListOfAllAlbumsCreated() {
return listOfAllAlbumsCreated;
}// I only want PlayList Class to Access this!
}
基本上,每当创建相册对象时,“listOfAllAlbumsCreated”都会将该对象添加到其中。然后,我创建了一个 PlayList 类,它应该可以访问创建的所有专辑 - 通过获取“listOfAllAlbumsCreated”并向其分配另一个 ArrayList。
public class PlayList {
private static ArrayList<Album> allExistingAlbums = Album.getListOfAllAlbumsCreated();
public PlayList(String playListName) {
this.playListName = playListName;
}
}
然而,这允许其他类中的任何人只调用Album.getListOfAllAlbumsCreated,并可能更改我显然不希望创建的所有相册的内容。那么我怎样才能保证 listOfAllAlbumsCreated 的安全;即只能由我的 PlayList 类访问?
谢谢!
最佳答案
是的,这是可能的。我想到了两个选择。
选项 1:通过访问修饰符限制访问。
Oracle tutorial on access control对不同访问修饰符的作用有一个简洁的表格概述(使用 Senseful 生成表格):
╔═════════════╦═══════╦═════════╦══════════╦═══════╗
║ Modifier ║ Class ║ Package ║ Subclass ║ World ║
╠═════════════╬═══════╬═════════╬══════════╬═══════╣
║ public ║ Y ║ Y ║ Y ║ Y ║
║ protected ║ Y ║ Y ║ Y ║ N ║
║ no modifier ║ Y ║ Y ║ N ║ N ║
║ private ║ Y ║ N ║ N ║ N ║
╚═════════════╩═══════╩═════════╩══════════╩═══════╝
根据您的描述,private
修饰符(仅授予当前类内的访问权限),no modifier
(仅授予当前类和同一包中的类的访问权限)或 protected
修饰符(从当前类、同一包中的类和派生类中授予访问权限)可能就是您正在寻找的。该示例显示了没有修饰符的情况。
static ArrayList<Album> getListOfAllAlbumsCreated() {
return listOfAllAlbumsCreated;
}
选项 2:返回列表的不可修改 View 。
返回 List
的不可修改 View 穿过 Collections.unmodifiableList(...)
。您的代码将如下所示:
public static ArrayList<Album> getListOfAllAlbumsCreated() {
return Collections.unmodifiableList(listOfAllAlbumsCreated);
}
关于不可修改列表的两句话警告:
- 对原始内容所做的更改
List
在您调用getListOfallAlbumsCreated()
之后不会反射(reflect)在不可修改的 View 中。不可修改的 View 只是您创建不可修改的 View 时的 ListView 。 - 而返回
List
不可修改,List
中的条目不是。 Java没有const
的概念对象,就像 C++ 那样。为了实现真正的不变性,您需要设计您的Album
类是不可变的。 future ,我们很可能会有value types ,这将简化不可变的实现,并带来一些巧妙的性能优势。
两个设计备注:
您所做的基本上是重新创建 Java,相当于内存泄漏。
Album
的一个实例不会被垃圾收集,除非您也将其从listOfAllAlbumsCreated
中删除。 。这可能是也可能不是您想要的。你能做的就是使用WeakReference
s ,为了允许对象的垃圾收集,只要WeakReference
该对象存在。你会改变listOfAllAlbumsCreated
至List<WeakReference<Album>>
。反过来,这可能会导致某些引用返回null
的情况。当您调用get()
时在他们。您可以尝试通过覆盖finalize()
来解决此问题方法,但强烈建议不要这样做。如果您已经为您的
Album
进行了某种簿记。 s,您可以实现 Factory Method Pattern或Builder Pattern以防止创建重复项。有关更完整的示例,您可能需要查看Integer.valueOf(int value)
的实现.
关于java - 尝试保持 ArrayList 不可变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49967933/