java - 尝试保持 ArrayList 不可变

标签 java list mutable

所以我有一个名为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该对象存在。你会改变listOfAllAlbumsCreatedList<WeakReference<Album>> 。反过来,这可能会导致某些引用返回 null 的情况。当您调用get()时在他们。您可以尝试通过覆盖 finalize() 来解决此问题方法,但强烈建议不要这样做。

  • 如果您已经为您的Album进行了某种簿记。 s,您可以实现 Factory Method PatternBuilder Pattern以防止创建重复项。有关更完整的示例,您可能需要查看 Integer.valueOf(int value) 的实现.

关于java - 尝试保持 ArrayList 不可变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49967933/

相关文章:

java - 使用 Java 和 PHP 的 AES CBC 128 位加密

Java - Vaadin - 表未填充

java-session.getattribute 返回 null

c# - 如何查找时间是否在一组范围内?

java - Java SE 6 或 Java SE 7 中是否有非最终字段

java - 抽象类的实例

c# - 将对象转换为列表

python-3.x - 如何计算列表中的连续几周?

rust - 添加时对 i32 的不可变和可变引用有什么区别?

c++ - boost::序列化可变成员