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

java static关键字

2015-07-18 22:00 711 查看
1、static变量

static 变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,存在于内存中,在内存中只有一个副本,它当且仅当在类初次被加载时会被初始化。

而非静态变量是对象所拥有的,在创建对象时被初始化,存在多个副本,各个对象所拥有的副本互不影响。

static是不允许用来修饰局部变量的。即使是在静态方法里面。

2、static方法

static方法也称为静态方法,静态方法不依赖于任何对象就可以访问,因为不依赖于任何对象,所以静态方法不可以访问非静态成员变量和非静态成员方法,因为非静态成员变量和非静态成员方法是依赖于对象的。

示例:

public class month {
private static String str="staticString";
private String str1="String";

public static void method(){
System.out.println(str);
System.out.println(str1);
method1();
}

public void method1(){
System.out.println(str);
System.out.println(str1);
method();
}
}




总结:因为静态成员和静态方法在类刚被加载时就被初始化了,所以只要调用类,静态方法和静态成员变量就已经存在。而非静态方法和非静态成员变量,必需在类被实例化以后才会有。

非静态方法可以访问静态成员变量和静态方法。

静态方法不能访问非静态成员变量和非静态方法。

3、静态代码块

static还可以用来形成静态代码块来优化程序,static代码块可以置于类的任何位置,static代码块会在类被初次加载的时候,按照static代码块的顺序执行,并且只被执行一次。

示例:

判断某人生日是不是在生育高峰期。

public class Person{
private Date birthDate;

public Person(Date birthDate){
this.birthDate=birthDate;
}

boolean isBornBoomer(){
Date startDate =new Date(46,1,1);
Date endDate = new Date(64,11,30);

return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate)<0;

}
}


如果换做如下代码,代码的效率会高很多。

public class Person{
private Date birthDate;
private static  Date startDate,endDate;
static {
Date startDate =new Date(46,1,1);
Date endDate = new Date(64,11,30);
}

public Person(Date birthDate){
this.birthDate=birthDate;
}

boolean isBornBoomer(){

return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate)<0;

}
}


其中startDate和endDate作为静态变量被定义,而他们初始化是作为静态代码块实现的,也是在类被加载时运行一次。其实在定义startDate和endDate时可以直接进行初始化,这样写只是为了理解。

4、static面试题

看一下代码的执行结果

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类时,发现Test类继承了Base类,所以先去加载Base类,在加载Base类时,发现有static代码块,所以就在加载Base类时,执行static代码块,输出base static,加载完Base类后,转去加载Test类,加载Test类时,也执行了static代码块,输出test static,在这两个类都加载完后,开始执行main函数,构造Test类,构造Test类先调用父类的构造器,然后再调用自身的构造器,所以输出以上结果。

5、static面试题

看一下代码的输出结果:

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


分析:

首先程序会加载Test类,然后执行static代码块,输出test static,然后开始执行main函数, new MyClass(),然而MyClass类还没有被加载,开始加载MyClass类,MyClass继承了Test类,而Test类已经被加载,就不再执行加载,开始加载MyClass,并执行static代码块,输出myclass static,加载完成后,通过构造器生成对象,而生成对象的时候,必须先初始化父类的成员变量,而成员变量中Person类还没有被加载,于是加载Person,并执行static代码块,输出person static,加载完成后,开始实例化Person,调用Person的构造函数,输出person test,然后调用Test构造函数,输出test constructor,然后开始初始化MyClass的成员变量,调用Person构造函数,输出person myclass,最后调用自身的构造函数,输出myclass constructor。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  关键字