Java基础篇(一):实例方法和静态方法有什么不一样
开始写这个是因为昨天看到一个大牛在简书写的文章,其中分门别类提了很多问题,我发现对于java我竟如此陌生,因此打算通过写文的方式来记录对这些问题的解答和理解,以此来加深我对Java的认识。
首先,当然要附上该文的链接——http://www.jianshu.com/p/ba0fdee47cb4
然后,开始对问题进行解(bai)答(du)吧!
实例方法和静态方法的区别
StaticAndNon-static.png
首先还是从个人感觉还是说吧,完全度娘谷哥涯妹简叔未免太没有诚意了。
- 从调用上来看,实例方法需要使用对象来调用,如果类没有实例化是无法调用实例方法的;反过来,静态方法则是由类直接调用的(对象也可以调用,编译可以通过,但不知道会不会有什么问题)。
2.在同一个类中,实例方法内部 可以直接使用静态方法,但是静态方法中则无法直接调用这个实例方法(编译无法通过,同样也无法直接访问非静态的成员变量),个人推测是因为两种方法的加载机制有差异,因为在类内部直接调用类持有的实例方法时,默认带有this关键字,this关键字只带当前类的对象,但是静态方法在加载时,类还没有实例化,因为不能调用实例方法
3.介于实例方法和静态方法的修饰符有差异,这也算是一种不一样吧。另外,实例方法属于对应类的实例的行为,而静态方法是属于类的行为(其实每一个类都是Class类的对象,那静态方法是不是Class的实例方法呢,表示不懂);
4.静态方法多用作工具类的方法。
以上就是我个人的理解,也许漏洞百出吧,接下来是网搜整理时间。
network.png
摘自:http://blog.csdn.net/biaobiaoqi/article/details/6732117
1、大家都以为“** 静态方法常驻内存,实例方法不是,所以静态方法效率高但占内存。**”
事实上,他们都是一样的,在加载时机和占用内存上,静态方法和实例方法是一样的,在类型第一次被使用时加载。调用的速度基本上没有差别。
2、大家都以为“ 静态方法在堆上分配内存,实例方法在堆栈上”
事实上所有的方法都不可能在堆或者堆栈上分配内存,方法作为代码是被加载到特殊的代码内存区域,这个内存区域是不可写的。
方法占不占用更多内存,和它是不是static没什么关系。 因为字段是用来存储每个实例对象的信息的,所以字段会占有内存,并且因为每个实例对象的状态都不一致(至少不能认为它们是一致的),所以每个实例对象的所有字段都会在内存中有一分拷贝,也因为这样你才能用它们来区分你现在操作的是哪个对象。 但方法不一样,不论有多少个实例对象,它的方法的代码都是一样的,所以只要有一份代码就够了。因此无论是static还是non-static的方法,都只存在一份代码,也就是只占用一份内存空间。 同样的代码,为什么运行起来表现却不一样?这就依赖于方法所用的数据了。主要有两种数据来源,一种就是通过方法的参数传进来,另一种就是使用class的成员变量的值……
3、大家都以为“实例方法需要先创建实例才可以调用,比较麻烦,静态方法不用,比较简单”
事实上如果一个方法与他所在类的实例对象无关,那么它就应该是静态的,而不应该把它写成实例方法。所以所有的实例方法都与实例有关,既然与实例有关,那么创建实例就是必然的步骤,没有麻烦简单一说。
当然你完全可以把所有的实例方法都写成静态的,将实例作为参数传入即可,一般情况下可能不会出什么问题。
从面向对象的角度上来说,在抉择使用实例化方法或静态方法时,应该根据是否该方法和实例化对象具有逻辑上的相关性,如果是就应该使用实例化对象 反之使用静态方法。这只是从面向对象角度上来说的。
如果从线程安全、性能、兼容性上来看 也是选用实例化方法为宜。
我们为什么要把方法区分为:静态方法和实例化方法 ?
如果我们继续深入研究的话,就要脱离技术谈理论了。早期的结构化编程,几乎所有的方法都是“静态方法”,引入实例化方法概念是面向对象概念出现以后的事情了,区分静态方法和实例化方法不能单单从性能上去理解,创建c++,java,c#这样面向对象语言的大师引入实例化方法一定不是要解决什么性能、内存的问题,而是为了让开发更加模式化、面向对象化。这样说的话,静态方法和实例化方式的区分是为了解决模式的问题。
上面的文字,更多是解释了很多对实例方法和静态方法理解的误区,同时也侧面反映了一些静态方法与实例方法的差异化。
对于实例方法来说,他是针对于对象的,也就是这一类型的不同个体,不同的个体可以有不同的属性,虽然是相同的行为(即实例方法,同时入参相同),但是不同的属性可能导致不同的结果;
对于静态方法来说,是无视个体差异的,同时静态方法内无法访问非静态成员属性,而静态成员属性相对于类来说永远只有一份,这样一来,相同的行为下结果必然是稳定不受其他因素影响的,因此更适合来做工具类这种全局函数。
想来想去,从静态方法到实例方法,也许就是从结构化到面向对象的一个缩影吧~
嗯,下一篇还是从文首链接中引入的一个问题——Java中的异常有哪几类?分别怎么使用?