我是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;在列表中?
请帮忙。
答案 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<>();
它将按预期工作,因为现在您将一个不同的实例与第二篇文章相关联,第一篇文章持有对第一个实例的引用。