java static关键字
2016-03-23 16:45
585 查看
static关键字用途
《Java编程思想》中讲到:static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通关过类本身来调用static方法。这实际上正是static方法的主要用途。
简而言之:方便在没有创建对象的时候进行调用(方法/变量)
显然,被static关键字修饰的方法或变量不需要依赖对象来进行访问,只要类被加载了,就可以通过类名去进行访问。
(1)static变量
static变量又被称为静态变量,静态变量和非静态变量的区别:静态变量被所有对象共享,在内存中只有一个副本,当且仅当在类被初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。
(2)static方法
static方法又被称为静态方法,在静态方法中不能访问非静态成员变量和非静态成员方法,但非静态方法可以调用静态方法和静态成员变量。因为静态方法不依附任何对象,而非静态成员方法/变量都是必须依赖具体的对象才能够被调用的。
因为static方法独立于任何实例,因此static方法必须被实现,而不能是抽象的abstract。
(3)static代码块
static代码块的作用就是形成静态代码块以优化程序性能。static块可以置于类中任何地方,类中可以有多个static代码块。在类被初次加载的时候,会按照每个static代码块的顺序来执行每个static块,并且只会执行一次。
为什么说static块可以优化性能,那是因为static在类加载时只执行一次。
常见误区
static是否会改变类中成员的访问权限?java中的static关键不会影响成员或方法的作用域,影响其作用域的只有private, public, protected这几个关键字。
this能访问静态成员变量吗?
public class STATICAPP { static int num = 3; public void printValue(){ int num = 33; System.out.println(this.num); } public static void main(String[] args) { // TODO Auto-generated method stub STATICAPP sa = new STATICAPP(); sa.printValue(); } }
输出结果:3
this表示当前实例对象,和成员方法中的局部变量无关。
static能作用于局部变量吗?
记住:static是不允许用来修饰局部变量的,Java语法规定
常见面试题
下面列举一些面试笔试中经常遇到的关于static关键字的题目,仅供参考,如有补充欢迎下方留言。1.下面这段代码的输出结果是什么?
public class Test extends Base{ static{ System.out.println("test static"); } public Test(){ System.out.println("test constructor"); } public static void main(String[] args) { new Test(); } } class Base{ static{ System.out.println("base static"); } public Base(){ System.out.println("base constructor"); } }
base static test static base constructor test constructor
开始执行时,首先要找到main方法,在执行main方法前,要首先加载Test类,当加载Test类时,发现它继承Base类,要首先加载Base类,这个时候发现Base类中存在static代码块,加载执行static块,加载Base完成后加载Test类,Test类中也存在static代码块,执行后开始执行main方法,首先调用Test父类的构造方法,然后调用Test自身的构造方法,就出现了上面的结果。
2.这段代码的输出结果是什么?
public class Test { Person person = new Person("Test"); static{ System.out.println("test static"); } public Test() { System.out.println("test constructor"); } public static void main(String[] args) { new MyClass(); } } class Person{ static{ System.out.println("person static"); } public Person(String str) { System.out.println("person "+str); } } class MyClass extends Test { Person person = new Person("MyClass"); static{ System.out.println("myclass static"); } public MyClass() { System.out.println("myclass constructor"); } }
test static myclass static person static person Test test constructor person MyClass myclass constructor
同样的道理,在执行开始,要先找到main方法,在执行main方法前,加载Test类,执行Test中的static块,然后执行main方法,new MyClass()之前先加载MyClass类,然后开始创建对象:因为MyClass继承Test类,所以要先初始化父类的成员变量(此时父类Test已经加载),因此会执行Test中的Person person = new Person(“Test”),此时还没有加载Person类,加载Person类执行Person类中static块,调用Person构造方法,实例化Person类,然后调用父类Test构造器,然后初始化自身,同样的道理,先初始化自己的成员变量,调用Person类的构造函数(此时Person已经加载过),最后执行MyClass的构造器。
3.这段代码的输出结果是什么?
public class Test { static{ System.out.println("test static 1"); } public static void main(String[] args) { } static{ System.out.println("test static 2"); } }
test static 1 test static 2
参照上述的分析过程:在执行main方法前,加载Test类,顺序执行Test类中的static块
参考文献:
http://www.cnblogs.com/dolphin0520/p/3799052.html
相关文章推荐
- 一个关于if else容易迷惑的问题
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- Python动态类型的学习---引用的理解
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序