对象列表松散属性值

时间:2016-11-12 11:08:34

标签: arraylist properties

我是Java编程的新手,因此如果这很简单,请提前道歉,但我无法弄明白。

我有以下代码:

文章如下:

公共类文章{

private String title;
private String author;
private List<String> tags;

我的主要代码旨在创建文章的Arraylist,如下所示:

    List<Article> myArticles = new ArrayList<Article>();
    List<String> myTags = new ArrayList<String>();

    String title;
    String author;

    title = "Pillars of the Earth";
    author = "Ken Follet";
    myTags.add("fiction");
    myTags.add("historical");
    myTags.add("best seller");

    myArticles.add(new Article(title, author, myTags));

    System.out.println(myArticles.get(0).toString());

    title = "Programming with java";
    author = "Louw Pieters";
    myTags.clear();
    System.out.println("myTags size : "+myTags.size());
    myTags.add("java");
    myTags.add("programming");
    myTags.add("best seller");

    myArticles.add(new Article(title, author, myTags));

    for (Article myItem : myArticles) {
        System.out.println(myItem.toString());
    }

我得到以下输出:

文章[title =地球的支柱,作者= Ken Follet,标签= [小说,历史,畅销书]]

myTags大小:0

文章[title =地球的支柱,作者= Ken Follet,tags = [ java,编程,畅销书]]

文章[title =用java编程,作者= Louw Pieters,tags = [java,programming,best seller]]

为什么它会更改“存储”的第一个文章对象的标记。在列表中。我以为它会受到保护&#39;在列表中?

请帮忙。

1 个答案:

答案 0 :(得分:0)

private List<String> tags;

将标记定义为Article类实例的字段。这意味着当标签收到一个值时,它的对象接收该值将保持对该值的引用,只要它是活动的(不是垃圾收集)。

即使你有一个

List<Article> myArticles = new ArrayList<Article>();

这并不意味着当Article的实例放入List时,tags元素将受到保护。 List还保留了添加到其中的每个元素的引用。

所以当你使用这个指令时:

myTags.clear();

你实际上清空了与第一篇文章相关的标签 当您创建第二篇文章并在其构造函数中使用相同的引用变量myTags时:您还将myTags与第二篇文章相关联,这就是为什么在更改标记后,两篇文章现在都显示相同的标记列表

如果你想避免这种情况,而不是

myTags.clear();

使用

myTags = new ArrayList<>();

它将按预期工作,因为现在您将一个不同的实例与第二篇文章相关联,第一篇文章持有对第一个实例的引用。