Java对象的引用机理

我们都知道Java是一个面向对象的编程语言,那么java对象究竟是如何创建和操作的呢?

Demo demo=new Demo();

首先我们看上面这一段代码,虽然很简单却有着其内部的一些机理。前面的Demo demo是一个引用的创建,而后面new Demo();则是一个对象的创建。如果把对象当作一个电视的话,引用实际上相当于一个遥控器。
为了弄清楚其中发生了什么,我们首先要知道两者存储位置的一些差别。对象存储在堆中,因为其内存和生命周期都是不确定的,需要动态分配并且不能确定其占用内存需要回收的时间。而引用实际上是一小段指向对象所在堆地址的确切的地址数值,其大小是确定的,并且拥有可以确定的生命周期,所以引用在栈中。知道了这些我们再看第一句代码,new在堆中创建了一个Demo对象,然后在栈中创建了一个Demo引用,最后用等号给引用赋值,让引用指向Demo对象的地址,这句话就完整的执行完了。

class Demo{
	public void hello() {
		System.out.println("hello!");
	}
}
public class test {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Demo demo=new Demo();		
}
}

我们看上面这段代码,当程序运行完时,demo这个引用变量由于其生命周期结束,分配的栈内存会立即被会回收,但是在堆中的对象却不会,而是等待虚拟机在一个不确定的时间对它进行回收,这是两者在生命周期上的差别。

Demo demo=new Demo();
Demo demo2=demo;

我们再看上面这段代码,这样执行的结果是demo和demo2实际表示的是同一个对象,他们都记载着同一个Demo对象所在堆地址,所以如果使用其中一个更改,整个对象都会被更改。

class Demo{
	int a;
	public void add() {
		a++;
	}
}
public class test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Demo demo=new Demo();
		Demo demo2=demo;
		demo2.add();
		System.out.print(demo.a);
		
}
}

上面这段代码最终输出的结果就是1。由于堆中的数值会自动初始化,所以a的初值会自动设为0,对demo2引用的对象进行a++,实际上也就是对demo所引用的对象进行a++,从中我们就很好看出两者的关系。一个对象可以被多个引用指向,而一个引用只能指向一个对象。
在c++中我们同样学过对象相关的内容,对比来看,c++中的对象和Java中有什么不同呢?
首先,在c++中,Demo demo;就意味着创建了一个Demo的对象,而Java中这么做则是创建了一个引用。其次,Java中没有指针这个概念,使用引用来操作对象,而c++中则需要通过指针来操作对象。

//c++
Demo *demo=new Demo();
    demo->add();
    demo->say();

对比Java来说指针的使用很容易出错,而且难度也很大,所以Java取消指针而采用引用可以说方便了不少。当然引用和指针有诸多区别,比如指针可以计算而引用并不能。指针可以计算直接的问题就在于指针可能会指向一些奇怪的地方,一些不应该由本程序操作的地方,这是非常危险的,对于我们程序员来说也是不好控制的。而引用则永远不会作用在程序意外的地方。所以对比来看引用安全,没有大小且不可计算。但是使用指针也有指针的好处,因为指针的使用更加灵活高效,直接在地址上进行运算使得c++的数组存取效率高于Java。综合来说两者各有优略,虽然本质上都是想指向要操作的东西,但使用时要注意区分,不能混为一谈。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值