A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 花开~的季节 黑马帝   /  2012-3-10 10:48  /  2159 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

java类中的方法在运行的时候,存在什么区,比如说对象时在堆栈区,

9 个回复

倒序浏览
方法都存在于对象中,这也是我们调用方法必须制定对象的原因。那么对象在执行的时候都存在于什么地方呢,
java对象一般存储在堆中,需要一个对象时,只需要new写一行简单的代码,当执行这行代码时,会自动在堆里进行存储分配。
回复 使用道具 举报
如果不是静态方法的话,应该是和对象在堆中。
回复 使用道具 举报
杨波 发表于 2012-3-10 11:05
方法都存在于对象中,这也是我们调用方法必须制定对象的原因。那么对象在执行的时候都存在于什么地方呢,
j ...

我觉得也不能一概而论把,静态方法呢,静态方法是不需要实例就可以调用的。而且即使是实例方法,但是方法本身是算法逻辑,与实例相关的也只是 使用对象的数据域,从这个方面讲,方法也不应该存储到对象中吧。我也不太清楚,但是我想大胆假设一下,我门是不是可以联想到“this“关键字,如果所有的方法存储在一个专门的区域,而静态方法的区别与实例方法的区别仅仅是:
、静态方法不实用实例相关的数据,而实例方法可以使用实例相关的数据。
那么 是用使用this关键字代表实例,那么,实例方法与静态方法存储在一个共同的区域是可行的,只需要一个 简单的过程就可以
1,在编译时 将 实例方法用到的实例数据域 与this 关联,调用的时候 从 存储方法的区域加载方法,然后将该实例赋于方法中的this 即可!
我觉得我能想到的,牛人一定能想到,也许会更巧妙也说不定。
以上是我的假设,和想像,不知道是否正确,但是我认为 将实例方法与对象完全绑定在一起 是不明智的选择,
这样以来,方法逻辑等于是在每次创建对象时都在复制,这个面向对象思想也是不相符的。
我突然想到其实我的方法也是在某种程度上得到验证的

我门可以想一想 每一个类的Class 实例 都是 单例的(这个我在以前的姨个回复中好像已经验证过了,应该老师也会讲过。),对应的 Mothed 实例是不是单例的 我们一直没人追究,如果Mothed 实例也是 单例,是不是可以证明我的说法呢 ?我等一下 测试一下 在发布答案 {:soso_e113:} 。

评分

参与人数 1技术分 +2 收起 理由
职业规划-刘倩老师 + 2 赞一个!

查看全部评分

回复 使用道具 举报
刚才又搜了一下网络,有人已经做了非常好的总结了,我上面是一个思考的思路,下面是牛人的总结:
总结:大家对这个问题都有一个共识:那就是实例化方法更多被使用和稳妥,静态方法少使用。

有时候我们对静态方法和实例化方法会有一些误解。

1、大家都以为“ 静态方法常驻内存,实例方法不是,所以静态方法效率高但占内存。”

事实上,他们都是一样的,在加载时机和占用内存上,静态方法和实例方法是一样的,在类型第一次被使用时加载。调用的速度基本上没有差别。

2、大家都以为“ 静态方法在堆上分配内存,实例方法在堆栈上”

事实上所有的方法都不可能在堆或者堆栈上分配内存,方法作为代码是被加载到特殊的代码内存区域,这个内存区域是不可写的。

方法占不占用更多内存,和它是不是static没什么关系。  
  因为字段是用来存储每个实例对象的信息的,所以字段会占有内存,并且因为每个实例对象的状态都不一致(至少不能认为它们是一致的),所以每个实例对象的所以字段都会在内存中有一分拷贝,也因为这样你才能用它们来区分你现在操作的是哪个对象。  
  但方法不一样,不论有多少个实例对象,它的方法的代码都是一样的,所以只要有一份代码就够了。因此无论是static还是non-static的方法,都只存在一份代码,也就是只占用一份内存空间。  
  同样的代码,为什么运行起来表现却不一样?这就依赖于方法所用的数据了。主要有两种数据来源,一种就是通过方法的参数传进来,另一种就是使用class的成员变量的值……

3、大家都以为“实例方法需要先创建实例才可以调用,比较麻烦,静态方法不用,比较简单”

事实上如果一个方法与他所在类的实例对象无关,那么它就应该是静态的,而不应该把它写成实例方法。所以所有的实例方法都与实例有关,既然与实例有关,那么创建实例就是必然的步骤,没有麻烦简单一说。

当然你完全可以把所有的实例方法都写成静态的,将实例作为参数传入即可,一般情况下可能不会出什么问题。

从面向对象的角度上来说,在抉择使用实例化方法或静态方法时,应该根据是否该方法和实例化对象具有逻辑上的相关性,如果是就应该使用实例化对象  反之使用静态方法。这只是从面向对象角度上来说的。

如果从线程安全、性能、兼容性上来看  也是选用实例化方法为宜。

我们为什么要把方法区分为:静态方法和实例化方法 ?

如果我们继续深入研究的话,就要脱离技术谈理论了。早期的结构化编程,几乎所有的方法都是“静态方法”,引入实例化方法概念是面向对象概念出现以后的事情了,区分静态方法和实例化方法不能单单从性能上去理解,创建c++,java,c#这样面向对象语言的大师引入实例化方法一定不是要解决什么性能、内存的问题,而是为了让开发更加模式化、面向对象化。这样说的话,静态方法和实例化方式的区分是为了解决模式的问题。

拿别人一个例子说事:

比如说“人”这个类,每个人都有姓名、年龄、性别、身高等,这些属性就应该是非静态的,因为每个人都的这些属性都不相同;但人在生物学上属于哪个门哪个纲哪个目等,这个属性是属于整个人类,所以就应该是静态的——它不依赖与某个特定的人,不会有某个人是“脊椎动物门哺乳动物纲灵长目”而某个人却是“偶蹄目”的。
回复 使用道具 举报
方法都在方法区。方法区又分为静态区和非静态区。
静态方法和静态属性放在静态区。
非静态区存放非静态方法。
堆内存区存放的是对象的特有属性。
回复 使用道具 举报
袁野 黑马帝 2012-3-10 14:19:06
7#
方法区 都是方法
局部都在栈
成员  new  的都在堆 你画图看看
回复 使用道具 举报
段玉超 发表于 2012-3-10 11:44
刚才又搜了一下网络,有人已经做了非常好的总结了,我上面是一个思考的思路,下面是牛人的总结:
总结:大 ...

以后回帖尽量不要这样一次发太多别人总结的东西,大家共同学习分享是值得鼓励的,但是我希望回答别人的问题时,最好是用自己整理的通俗易懂的语言回答问题,这样会显得非常的简洁明了易懂
回复 使用道具 举报
java的内存分为两类,一类是栈内存,一类是堆内存。
栈内存是指程序进入一个方法时,会为这个方法单独分配一块私属存储空间,用于存储这个方法内部的局部变量,当这个方法结束时,分配给这个方法的栈会释放,这个栈中的变量也将随之释放。
堆是与栈作用不同的内存,一般用于存放不放在当前方法栈中的那些数据,例如,使用new创建的对象都放在堆里,所以,它不会随方法的结束而消失。方法中的局部变量使用final修饰后,放在堆中,而不是栈中
回复 使用道具 举报
刘老师 发表于 2012-3-10 14:29
以后回帖尽量不要这样一次发太多别人总结的东西,大家共同学习分享是值得鼓励的,但是我希望回答别人的问 ...


这个 我只是想说 有人总结的正好验证了我上面的想法。以后一定会注意的,谢谢老师提醒。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马