您的位置:首页 > 编程语言 > Java开发

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息