实例方法和静态方法有什么不一样?

面试造航母,工作拧螺丝,面试好像几乎是技术人员面临频率较高的问题,不是面试别人就是别人面试自己,那针对各种各样的面试,该怎么回答呢。今天就把之前遇到的一个面试问题来分析一下,下面是本文大纲

  1. 复现之前的面试问答
  2. 分析static关键字
  3. 从不同的方面来回答面试官的问题

面试问答

某年某月某日的一场对话:
面试官:说一下实例方法和静态方法有什么不同的地方吧?
我:静态方法只能访问静态成员,可以使用类名.方法名或者对象名.方法名,但是不推荐使用后者。而实例方法可以访问静态成员也可以访问非静态成员,只能使用对象名.方法来调用。因为静态方法是属于类的,实例方法依赖于对象,就这么点区别吧!
面试官:嗯好(心里全是mmp)
我内心觉得这样的回答还是很不错的嘛,但是实际上从面试官的反应来看,可能他不是很喜欢我的回答!。。。
我后来就专门研究了一下这个东西,原来自己回答的真的很一般,首先根据这个问题我们先拆分一下都需要哪方面的知识,静态方法,实例方法分别是什么,jvm是怎么加载的,然后两者的区别在哪里。

static关键字的作用

在java语言中,static表示“静态”的意思,使用的场景可以用来修饰成员变量和成员方法,当然也可以是静态代码块,static的作用主要在于创建独立于具体对象的域变量或者方法

静态变量和静态方法一样,都是属于类本身,而不是属于那个类的对象。也就是说静态方法的调用不依赖于对象,可以直接【类名.方法名】来调用,但是实例方法必须依赖于对象才可以调用,为什么呢?类的静态方法,静态变量是在类装载的时候装载的,这时候还没有产生对象。具体的可以去看看类加载的机制
实例方法和静态方法有什么不一样?_第1张图片

静态方法于实例方法在加载期的区别:

java虚拟机(jvm)只有一个堆区被所有线程所共享,堆区中有一块特殊的区域叫做方法区(静态区),该区域也是被所有线程共享的,jvm保存的所有的信息都在这个方法区中,所以方法区在加载方法信息的时候是统一对待的,无论静态方法或实例方法,都在类第一次被使用时加载,时机上没有任何区别的

静态方法和实例方法的内存区别:

静态方法在程序开始时生成内存,实例方法在程序运行中生成内存,
所以静态方法可以直接调用,实例方法要先成生实例,通过实例调用方法,静态速度很快,但是多了会占内存,所以不管是任何语言都是对内存和磁盘的操作,至于是否面向对象,只是软件层的问题,底层都是一样的,只是实现方法不同。静态内存是连续的,因为是在程序开始时就生成了,而实例申请的是离散的空间,所以当然没有静态方法快,而且静态内存是有限制的,太多了程序会启动不了。
main函数的一个执行的过程类似于下方的:
实例方法和静态方法有什么不一样?_第2张图片

静态方法和实例方法调用的区别:

静态方法,通过类名调用即可。
实例方法,通过实例调用即可。
看起来除了修饰语不一样,其他并没有什么区别,事实也是如此。你完全可以把所有的实例方法都写成静态的,将实例作为参数传入即可,一般不会出什么问题,只是调用方式不一样。如果一个方法与他所在类的实例对象无关,那么它就应该是静态的,而不应该把它写成实例方法。所有的实例方法都与实例有关,既然与实例有关,那么创建实例就是必然的步骤。
从面向对象的角度上来说,在选择使用实例化方法或静态方法时,如果方法和实例化对象具有逻辑上的相关性,就应该使用实例化对象 反之使用静态方法。这只是从面向对象角度上来说的。如果从线程安全、性能、兼容性上来看 也是选用实例化方法为宜。从语言本身来看,JAVA是面向对象的语言,既然面向对象,那最好还是用实例化对象方法最合适。

扩展猜想

好奇是人们进步的不朽的动力源泉,那么作为方法为什么会有静态方法和实例方法的区分呢?

个人觉得从编程的历史发展来看,早期的语言面向过程,是结构化编程,几乎所有的方法都可以理解为是“静态方法”。而随着业务需求逐渐复制,分工协作体系庞大,便出现了面向对象编程,面向对象出现后就引入了实例化方法概念。区分静态方法和实例方法不能单单从性能上去理解,创建了c++,java,c#这样面向对象语言的大师引入实例化方法一定不是要解决什么性能、内存的问题,而是为了让开发更加模式化、面向对象化。所以,静态和实例的方式区分应该是为了解决开发模式的问题。分工细作,各司其职。
我想如果按照这样的一套逻辑下来回答最初的面试官的问题的话,面试官应该不会只回答一个哦吧
参考博博文:区别使用的场景

欢迎分享你的idea

若有不正,多多见谅!
若有雷同,算我抄你!

你可能感兴趣的:(面试必备)