您的位置:首页 > 编程语言 > Java开发

从关键字说Java对象、引用、指针、堆栈的关系

2015-01-06 22:14 288 查看
前言:上一篇中我们介绍了new关键字 点击打开链接,new一个类,实际上就是调用该类的构造函数,返回该类的对象。如a = new Animal();返回的对象赋给变量a。我们来分析一下内存分配的步骤,new一个类,实际上就创造了一个对象,就要为这个对象分配内存来存储成员变量,放在哪里?放在了堆内存中。那么把这个对象赋给a,需要再开辟一块儿堆内存然后复制成员变量么?答案是否定的。实际上a是一个引用变量,它只存储内存的地址,系统会让这个引用变量指向对象的内存,而不会重新开辟。所以,如果希望垃圾回收机制回收某个对象,那么只需要切断该对象所有引用变量和该对象(该内存空间)的关系,即a=null;内存将会自动被回收。

那么a存放在哪里?a存放在栈中。

this:this关键字引用(指向)调用该方法的对象。但倘若this出现在构造器中则是引用该构造器正在初始化的对象。那么this到底有什么用?我们会遇到这种情况,一个方法中需要调用另一个方法,由于调用任何方法都需要对象,那么如果调用的是本方法对象中的另一个方法,则用this关键字来表示这个对象。当然,不用this关键字,同一个对象中的方法可以相互调用,但是其本质还是隐式的调用了this方法。

那么问题就来了1:static修饰的方法中,是否可以调用非static修饰的成员方法?答案:否,因为调用方法实际上隐式的调用了this来告知对象是谁,但是static修饰的方法是属于类的,而不是属于对象的。所以无法找到对应该方法的对象。也就是不能使用this,也就无法调用其他方法了。

那么问题就来了2:static修饰的方法中,是否可以调用static修饰的成员方法?答案:是,因为调用static修饰的方法,实际上默认调用了该类(见点击打开链接),而不是this,又static修饰的方法可以找到该类,所以static调用static是可行的。

如果实在是必须在静态方法中调用非静态变量或方法,怎么办?那就只能在调用的时候重新申请对象:比如

System.out.println(new Animal().foot);
那么问题又来了,既然static这么不好使,为什么还要设置static这么个关键字?其实,其区别就在于使用static修饰的方法,无论对象是谁,调用的结果都一样。但是非使用static修饰的方法,不同的对象调用就会不同。比如static修饰了一个变量x,则无论创建多少实例,其调用的都是这个x。但是如果调用普通变量b,那么每次创建实例都要重新给b赋值。因为static变量是属于类的,其生存周期和类相同,但是普通变量是属于对象的,其生存周期与变量是相同的,对象不存在了,该变量就不存在了。

成员变量(无论是类变量还是对象变量)都存放在堆中,但是局部变量则存放于栈中,由于局部变量不需要系统垃圾回收,随着代码块儿或者方法的运行结束而结束,所以所占内存比较小。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息