Java——static

static

在类中,用static声明的成员变量为静态成员变量,也称为类变量。类变量的生命周期和类相同。在整个应用程序执行期间都有效。

一、static关键字的用途

《Java编程思想》:static方法就是没有this的方法,在static方法内部不能调用非静态方法。反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法,这实际上正是static方法的主要用途。

1、static关键字修饰方法

static方法一般称作静态方法,由于静态方法不依赖于任何对象就可以进行访问,因此对于静态方法来说,是没有this的,因为它不依赖于任何对象,既然没有对象,就谈不上this了,并且由于这个特性,在静态方法中不能访问类的非静态成员变量和非静态成员方法。
在这里插入图片描述
注意:static方法是属于类的,非实例对象,在JVM加载类的时候,就已经存在内存中,不会被虚拟机GC回收掉,这样内存负荷会很大,但是非static方法会在运行完毕后被虚拟机GC掉,减轻内存压力。

2、static变量

static变量也被称为静态变量,静态变量被所有对象所共享,在内存中只有一个副本,它当且仅当类初次加载时会被初始化。
然而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。

3、static代码块

静态代码块:用来提升程序性能;将一些需要进行一次初始化的操作都可以放在static代码块中。

看下面例子:

class Person{
    private Date birthDate;
     
    public Person(Date birthDate) {
        this.birthDate = birthDate;
    }
     
    boolean isBornBoomer() {
        Date startDate = Date.valueOf("1946");
        Date endDate = Date.valueOf("1964");
        return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0;
    }
}

isBornBoomer是用来这个人是否是1946-1964年出生的,而每次isBornBoomer被调用的时候,都会生成startDate和birthDate两个对象,造成了空间浪费,如果改成这样效率会更好:

class Person{
    private Date birthDate;
    private static Date startDate,endDate;
    static{
        startDate = Date.valueOf("1946");
        endDate = Date.valueOf("1964");
    }
     
    public Person(Date birthDate) {
        this.birthDate = birthDate;
    }
     
    boolean isBornBoomer() {
        return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0;
    }
}

二、static关键字的误区

1、static关键字会改变类中成员的访问权限吗?

不会。在Java中影响到访问权限的只有private,public,protected这几个关键字。
在这里插入图片描述

2、能通过this访问静态成员变量吗?

可以。

public class Main {  
    static int value = 33;
 
    public static void main(String[] args) throws Exception{
        new Main().printValue();
    }
 
    private void printValue(){
        int value = 3;
        System.out.println(this.value);//33
    }
}

这里面主要考察队this和static的理解。this代表什么?this代表当前对象,那么通过new Main()来调用printValue的话,当前对象就是通过new Main()生成的对象。而static变量是被对象所享有的,因此在printValue中的this.value的值毫无疑问是33。在printValue方法内部的value是局部变量,根本不可能与this关联,所以输出结果是33。在这里永远要记住一点:静态成员变量虽然独立于对象,但是不代表不可以通过对象去访问,所有的静态方法和静态变量都可以通过对象访问(只要访问权限足够)。

3、static能做用于局部变量吗?

在C/C++中static是可以作用于局部变量的,但是在Java中是不可以的。

三、static内存图

在这里插入图片描述

四、static相关面试题

1、下面代码的输出结果
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类,因此会先执行Test类中的静态代码块,接着执行MyClass中的静态代码块;
其次,开始生产对象,在生产对象时,会先初始化父类的成员变量,因此会执行Test类中的Person person = new Person();而此前Person没有被加载过,所以会先加载Person中的静态代码块,然后再执行Person的构造;然后加载Test的构造;完成之后开始初始化MyClass自身,所以会先执行Person person = new Person();最后执行MyClass的构造。

五、参考资料

http://lavasoft.blog.51cto.com/62575/18771/

http://www.51cto.com/specbook/24/35011.htm

http://blog.youkuaiyun.com/zhu_apollo/article/details/1888219

http://blog.sina.com.cn/s/blog_70b845780100n9zz.html

http://hi.baidu.com/yuiezt/item/b71ff5fbfe9c385cc8f3370d

http://bbs.youkuaiyun.com/topics/330251070

http://yezixingchen.iteye.com/blog/1597186

《Java编程思想》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值