对象和引用
来源:互联网 发布:游戏源码是什么 编辑:程序博客网 时间:2024/06/08 05:01
Student stu=new Student(); Student stu; stu=new Student();
想理解上面代码的含义,就要知道堆(heap)和栈(stack)的含义
堆(heap)—由new等指令创建的对象和数组,由Java虚拟机的自动垃圾回收来回收不再使用的数据
栈(stack)—基本类型的变量和对象的引用变量,当超过变量的作用域后,Java会自动释放掉该bl,内存空间可以立即被另作他用。注意: 栈内存储的除了基本类型的变量(int String…)还会存储对象的引用变量,java中,引用变量实际是一个指针,它指向堆内存中的对象实例。
引用变量就相当于是为数组或对象起的一个名称,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。
- 所以上面代码里的”=”并不是赋值的意思,而是把对象的地址传递给变量
- 对象创建出来,其实连名字都没有,因此必须通过引用变量来对其进行操作。
Case cc; //在栈内存里面开辟了空间给引用变量cc,这时cc=null cc=new Case(); //1. new Case()在堆内存里面开辟了空间给Case类的对象,这个对象名字 //2. Case()随即调用了Case类的构造函数 //3. 把对象的地址在堆内存的地址给引用变量cc
public class ObjectRef { '''基本类型的参数传递''' public static void testBasicType(int m) { System.out.println("m=" + m);//m=50 m = 100; System.out.println("m=" + m);//m=100 } '''参数为对象,不改变引用的值''' '''s即sMain指向的对象执行了append方法,在原来的字符串上加了段“_add”''' public static void add(StringBuffer s) { s.append("_add"); } '''参数为对象,改变引用的值 ''' '''引用变量指向了一个新的对象,已经不是sMain指向的对象了''' public static void changeRef(StringBuffer s) { s = new StringBuffer("Java"); } public static void main(String[] args) { int i = 50; testBasicType(i); System.out.println(i);'''i=50''' StringBuffer sMain = new StringBuffer("init"); System.out.println("sMain=" + sMain.toString());'''sMain=init''' add(sMain); System.out.println("sMain=" + sMain.toString());'''sMain=init_add''' }}
public class OOTest06 { public static void main(String[] args) { int i=10; method1(i); System.out.println(i); } public static void method1(int temp) { temp = 1; }}
以上代码执行过程,首先在栈中创建main方法栈帧,初始化i的值为10,将此栈帧压入栈,接着调用method1()方法,通常是在栈区创建新的栈帧,并赋值temp为1,压入栈中,两栈帧都是独立的,他们之间的值是不能互访的。然后method1()方法栈帧弹出,接下来执行输出i值的语句,因传递的是值,所以不会改变i的值,输出结果i的值仍然为10,最后将main方法栈帧弹出,main方法执行完毕。
结论:只要是基本类型,传递过去的都是值
public class OOTest07 { public static void main(String[] args) { //创建一个对象 Student student = new Student(); student.id = 1001; student.name = "张三"; student.sex = true; student.address = "北京"; student.age = 20; method1(student); System.out.println("id=" + student.id); System.out.println("name=" + student.name); System.out.println("sex=" + student.sex); System.out.println("address=" + student.address); System.out.println("age=" + student.age); } public static void method1(Student temp) { temp.name="李四"; }}class Student { //学号 int id; //姓名 String name; //性别 boolean sex; //地址 String address; //年龄 int age;}
程序执行流程
1. 执行main方法时,会在栈中创建main方法的栈帧,将局部变量student引用保存到栈中
2.将Student对象放到堆区中,并赋值
3.调用method1方法,创建method1方法栈帧
4.将局部变量student引用(也就是student对象的地址),传递到method1方法中,并赋值给temp
5.此时temp和student引用指向的都是一个对象
6.当method1方法中将name属性改为“李四”时,改的是堆中的属性
7.所以会影响输出结果,最后的输出结果为:李四
8.main方法执行结束,此时的student对象还在堆中,我们无法使用了,那么他就变成了“垃圾对象”,java的垃圾收集器会在某个时刻,将其清除,以上就是地址传递,也就是引用的传递
结论:除了基本类型外都是地址传递
将一个对象赋值给另一个对象”,实际是将“引用”从一个地方复制到另一个地方 ---引用《Java编程思想》
- 对象和对象引用
- 对象和对象引用
- 对象和对象引用
- 对象、引用和引用计数
- 引用和对象
- 对象 和 引用
- 引用和对象分析
- PHP 对象和引用
- 引用和对象
- java 对象和引用
- java引用和对象
- 返回引用和对象
- 对象继承和引用
- 对象和引用
- 对象传递和引用
- 对象和引用
- 对象指针和对象引用
- 对象指针和对象引用
- java子线程访问网络
- Android WebView和Native交互的3种方式总结
- cordova 安卓 android 物理 返回键 监听和处理
- 入职培训记录与心得
- java对数组进行排序
- 对象和引用
- 体脂肪丰乳注意事项
- iOS开发之高级视图—— UITableView(一)简单例子
- 省市区 三级联动 js 实现
- js本地储存web Storage和cookie的区别
- sqlserver 无法启动
- 中山大学软件工程操作系统实验三报告
- 子类是否可以继承父类的私有属性和方法?
- Solr开发