关于static的一些认识

来源:互联网 发布:水乳推荐20到25岁 知乎 编辑:程序博客网 时间:2024/05/18 02:51
static:
(一)static方法
1.在static方法内部不能直接调用非static方法/变量,需先创建对象(原因:静态方法/变量在类加载的时候就分配了内存块,而非静态方法/变量在new这个类的对象时才分配内存块,他们分配内存的时间不一样,所以static区域访问非static区域是没有意义的;也可以理解为,static方法/变量是属于类的,而非static方法/变量必须依附于对象才能被调用,所以在调用前要先创建对象。),而在非static方法内部可以调用static方法/变量 。

2.在没有创建任何对象的前提下,仅通过类本身就可以调用static方法/变量 (static方法/变量 的主要用途)。被static关键字修饰的方法/变量不需要依赖对象进行访问,只要类被加载了,就可以通过类名进行访问。

3.static修饰的方法/变量是属于类的,而不是专属于对象的。而this是当前对象的引用,也就是说只能用this来调用属于当前对象的方法/变量,如果使用类来调用而不是对象来调用,this就无法指向合适的对象,所以static方法就是没有this的方法(static不能和this、super一起使用)。

4.可以编写static代码块来优化程序性能。

5.类的构造器,可以算是静态方法(原因:静态方法可以在未创建对象时调用,而构造方法在对象未创建时调用,可以看作静态方法),也不完全是静态方法(原因:静态方法不能调用非静态方法,而构造方法可以调用非静态方法,所以构造器不算是静态方法)。---此说法有待考证
ps:简单说:
从Java语言层面看,构造器不是静态方法。事实上规范专门规定了构造器不是方法。
从JVM层面看,构造器属于特殊的初始化方法,但仍然不被归类为静态方法。
无论从哪个层面看,构造器都是可以静态分派的(statically dispatched)。但要特别注意的是,并非所有可以静态分派的代码都是静态方法,这是规范里有定义的术语。
无论从哪个层面看,构造器都要接收从调用方传入的隐藏this参数。Java的静态方法不需要接收该参数,而实例方法要接收该参数。这方面构造器更接近于可以静态分派的实例方法,例如私有实例方法。这就是为什么从构造器可以调用this上的实例方法。
书中的Dog例子,确实当Dog被首次实例化或其静态方法/静态变量被首次访问时,会触发Dog类的初始化。但构造器在此并不可以归类到静态方法的一侧。事实上构造器并不能被单独调用,而必须用在new表达式里,此时触发类初始化的正是new,而不是对构造器的调用——new与构造器调用是两码事。(关于构造器是否为static方法,参考地址:https://www.zhihu.com/question/35860619/answer/64802279 )

(二)static变量
1.静态变量和非静态变量的区别:
(1)静态变量被所有对象共享,在内存中只有一个副本,当且仅当在类初次加载时被初始化。
(2)非静态变量是对象所拥有的,在创建对象时被初始化,存在多个副本,各个对象拥有的副本互不影响。

(三)static代码块
static代码块可以存在类中的任何地方(但不能是方法内部),类中可以有多个static代码块。在类初次被加载的时候,按照static代码块的顺序执行每个static块,并且只执行一次。(特性:只在类加载的时候执行一次)

几个容易混淆的误区:
1.static不会影响变量或者方法的作用域,在java中能够影响到访问权限的只有public,private,protected这几个关键词。
2.所有的static方法/变量都可以通过对象访问。
3.在java中,static不允许用来修饰局部变量。
(参考资料:
http://lavasoft.blog.51cto.com/62575/18771/
http://www.51cto.com/specbook/24/35011.htm
http://blog.csdn.net/zhu_apollo/article/details/1888219
http://blog.sina.com.cn/s/blog_70b845780100n9zz.html
http://hi.baidu.com/yuiezt/item/b71ff5fbfe9c385cc8f3370d
http://bbs.csdn.net/topics/330251070
http://yezixingchen.iteye.com/blog/1597186

(题外话:
1.单独用{}包起来的称为代码块,java的代码块主要分为四种:普通代码块 构造代码块 static代码块 同步代码块
2.生成对象的时候,现初始化成员变量,然后再执行构造器

参考网址:
http://www.cnblogs.com/dolphin0520/p/3799052.html
0 0
原创粉丝点击