在看Java网课的时候,这门课第三周3.1的课后讨论提出了对于Java容器中存放的到底什么的问题,对于是值还是引用(理解为C中的地址)众说纷纭,因此进行实验。
首先进行课程样例的测试
程序中定义一个套娃ArrayList类(目的是学习类)
定义add、show等操作
main中将一个String对象add到其中,修改String对象,观察类对象中容器促组成是否改变
import java.util.ArrayList;
public class My_array_list
{
private ArrayList<String> note = new ArrayList<String>();
public My_array_list()
{
}
public void add(String s)
{
note.add(s);
}
public void show_list()
{
for(String i:this.note)
{
System.out.println(i);
}
}
public static void main(String[] args)
{
//first attempt
My_array_list my_note = new My_array_list();
String a = "First";
my_note.add(a);
my_note.show_list();
a = "Second";
my_note.show_list();
}
}
调试一下(观察右侧监视器)
类对象中容器管理的与a管理的同样是id=23的String实例“First”
在a改变值后,a管理id=50的String实例“Second”,而类对象中容器管理的认识id=23的String实例“First”
另一种方式
public static void main(String[] args)
{
//first attempt
My_array_list my_note = new My_array_list();
String b = "First";
String a = b;
my_note.add(a);
my_note.show_list();
a = "Second";
my_note.show_list();
}
使用另一个String对象b给a赋值
b给a赋值后,可以看到二者管理的其实是同一个id=24的String实例“Frist”
在进行add操作将a加入到类对象容器中后,可以看到三处的“First”都是id=24的String实例
而改变了a的值后,同样的没有对类对象容器中的String产生影响
改变容器存放的元素类型
将存放String的容器调整为存放Box类型元素的容器
import java.util.ArrayList;
public class My_array_list_box
{
private ArrayList<Box> note = new ArrayList<Box>();
public My_array_list_box()
{
}
public void add(Box b)
{
note.add(b);
}
public void show_list()
{
for(Box i:this.note)
{
i.show_string();
}
}
public static void main(String[] args)
{
//first attempt
My_array_list_box my_note = new My_array_list_box();
Box b = new Box("First");
my_note.add(b);
my_note.show_list();
b.modify("Second");
my_note.show_list();
}
}
Box类定义如下
public class Box
{
private static int num = 0;
private int id = 0;
private String s = "";
public Box(String st)
{
this.id = num++;
this.s = st;
}
public void modify(String st)
{
this.s = st;
}
public void show_string()
{
System.out.println(this.s);
}
}
调试一下
观察到含有id=41的String实例“First”的id=23的Box类对象已经被传入到类对象容器中了
在改变Box类对象中s属性值后,观察到Box类对象和类对象容器中的String实例均改为id=50的“Second”
总结一下
此次实验中String对象管理的是一个String类实例,如“First”,a充当一个管理者的角色,为a赋值实质上是改变其麾下的实例,而不是改变“First”这个实例,因此在将a传入容器是,传入的是String实例“First”的地址(Java中称作引用),就像我们把b赋值给a,实质上是把b管理的这个实例地址交给a,共同管理“First”这个实例。
在第二个实验中,我们将一个拥有String属性的Box类对象传入容器当中,在外部修改Box会对容器内产生影响的原因是:我们传入的不再是一个String实例,而是一个String实例的管理者,其指向“First”这个实例,因此对管理者进行的修改会在容器中展现。