Java中static的使用

来源:互联网 发布:linux 激活网卡 编辑:程序博客网 时间:2024/06/06 02:55

在Java中有一个非常重要的static静态修饰符,用于修饰成员变量或者成员方法,也可以用于修饰代码块。

这里对于几种常用的情况进行说明,

1.静态变量(static variable)

首先来说静态变量。和静态变量相对的就是实例变量(instance variable),两者对比最显而易见的区别就是静态变量只有一个,而成员变量能有多个,先看一段代码

首先定义了一个类,包含一个静态和一个非静态变量

class ForStaticVariable {    private static int static_i = 1;    private int instance_i = 1;    public int get_static_i() {        return static_i;    }    public int get_instance_i() {        return instance_i;    }    public void increase_static_i() {        static_i++;    }    public void increase_instance_i() {        this.instance_i++;    }}

然后执行接下来的代码:

        ForStaticVariable class1 = new ForStaticVariable();        ForStaticVariable class2 = new ForStaticVariable();        System.out.println("static_i of class1 is: " + class1.get_static_i());        System.out.println("instance_i of class1 is: " + class1.get_instance_i());        class1.increase_static_i();        class1.increase_instance_i();        System.out.println("after increase static_i of class1 is: " + class1.get_static_i());        System.out.println("after increase instance_i of class1 is: " + class1.get_instance_i());        System.out.println("after increase static_i of class2 is: " + class2.get_static_i());        System.out.println("after increase instance_i of class2 is: " + class2.get_instance_i());

运行结果

static_i of class1 is: 1instance_i of class1 is: 1after increase static_i of class1 is: 2after increase instance_i of class1 is: 2after increase static_i of class2 is: 2after increase instance_i of class2 is: 1

实际上静态变量在内存中只存在一份拷贝,并且在JVM加载outclass的时候就完成创建,除了创建类的实例进行访问外,也能够直接通过类名进行访问。而实例变量则是在创建一个类实例的时候才被创建。所以存在多份拷贝,也就是说有多少类实例存在对应的就有多少的该类包含的实例变量被创建。

总结来说就是常量可以被仅用一次内存而创建,即共享变量的使用节约了内存。同时能够不必创建实例对常量进行访问。

2.静态方法(static method)

静态方法,是在JVM加载outclass的时候就被创建的方法,所以可以直接通过类名调用,之前在StackOverflow上看到一个人回答过什么时候选择使用静态方法,我就将那个回答的大意写在本文中:有一个这样的法则,问自己不构建Obj而去直接调用方法是否有意义,如果有意义的话就让它变成一个静态方法。比方说你的汽车类Car里有一个方法,Car::convertMPpgToKpl(double mpg),可能有人需要使用转换的方法,但是并不需要一个Car实例。(附上原文链接)

Java: when to use static methods

总结来说使用静态方法的好处就是对于不依赖于实例存在的方法,能够避免在需要调用时去创建一个实例来访问该方法。

3.静态代码块(static code block)

用static修饰的代码块和未被修饰的代码块之间的区别,用下面的代码的来解释能够能加清楚,

class ForStaticCodeBlock {    static{        System.out.println("This is static code block.");    }    {        System.out.println("This is non-static block.");    }    public static void main(String[] args) {        ForStaticCodeBlock class1 = new ForStaticCodeBlock();        ForStaticCodeBlock class2 = new ForStaticCodeBlock();    }}

运行结果如下:

This is static code block.This is non-static block.This is non-static block.
总结来说呢,被static修饰的代码块的内容在创建类实例的时候会被执行且仅执行一次,而未被static修饰的代码块则在每次创建过程中都会被执行。所以通常情况下使用静态代码块来对类中的静态变量进行赋值。

4.静态内部类(static inner class)

对于这个概念,平时接触的较少,于是我还产生了几个疑问,并通过查阅资料解决了这些个问题。

首先,就是非静态内部类中为什么不能有静态变量,对于这个问题从Java装载的过程来考虑就容易想明白了。首先Java中有OutClass和InnerClass的区别,首先装载类然后初始化静态的内容,这里说到的类实际上是OutClass,那么就是说非静态内部类也就类似于类的实例变量,那么只有在创建类实例的时候才会被创建,所以在最初的时候InnerClass中定义的静态变量不会得到初始化,内存不能够被访问,显然和整个编译的过程相违背了。

然后,什么时候我们会使用静态内部类。说到静态内部类的使用,这个问题从内部类的定义上来说,存在着nested class和inner class的区别。

对于一个inner class来说,它能够访问成员变量,和它本身所在的OutClass有紧密的联系。而对于一个静态内部类(static nested class)来说,它不能够访问所在OutClass的非静态变量,从某种意义上来说和OutClass的关系没那么密切,同时能够通过OutClass类名来创建它的实例。

5.使用static和final同时修饰的变量

之前在静态内部类中提到,非静态内部类中不能够有静态变量,但是如果变量通过static final修饰的话就是能够存在的,于是我又查阅了一些资料。

简单的理解的话,被static final修饰的变量为全局常量。


代码地址:https://github.com/AlanJager/java_learning/blob/master/src/StaticTest.java




0 0
原创粉丝点击