static简述

来源:互联网 发布:手机淘宝6.11.0版本 编辑:程序博客网 时间:2024/06/06 00:43

1.当类装载的时候,只为static变量分配一块存储空间,所有此类的对象都是对这块存储空间进行读写的。

2.static方法不能调用none-static方法,仅能调用其他static方法,因为非静态方法有可能会调用实例变量,编译器不允许这种可能的存在。

3.静态初始化在类加载的时候执行且执行一次,位于其他语句之前执行。

static{//your code}

4.static方法只能访问static 数据

package p1;import java.util.ArrayList;public class Test {public static void main(String[] args) {String s = "sfs";System.out.println(s);}}


5.存在多个static块的时候,static变量的数值问题。

public class Test {static{a =  9;}static int a = 4;static String s;public static void main(String[] args) {System.out.println(s);}}
答案是4,通过查看字节码,我们可以清楚的看到其中赋值过程(字节码即.java文件编译后的.class文件,虚拟机读取的正是字节码)

// class version 49.0 (49)// access flags 0x21public class p1/Test {  // compiled from: Test.java  // access flags 0x8  static I a  // access flags 0x8  static <clinit>()V   L0    LINENUMBER 5 L0    BIPUSH 9    PUTSTATIC p1/Test.a : I   L1    LINENUMBER 7 L1    ICONST_4    PUTSTATIC p1/Test.a : I   L2    LINENUMBER 3 L2    RETURN    MAXSTACK = 1    MAXLOCALS = 0  // access flags 0x1  public <init>()V   L0    LINENUMBER 3 L0    ALOAD 0    INVOKESPECIAL java/lang/Object.<init>()V    RETURN   L1    LOCALVARIABLE this Lp1/Test; L0 L1 0    MAXSTACK = 1    MAXLOCALS = 1  // access flags 0x9  public static main([Ljava/lang/String;)V   L0    LINENUMBER 9 L0    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;    GETSTATIC p1/Test.a : I    INVOKEVIRTUAL java/io/PrintStream.println(I)V   L1    LINENUMBER 10 L1    RETURN   L2    LOCALVARIABLE args [Ljava/lang/String; L0 L2 0    MAXSTACK = 2    MAXLOCALS = 1}

由字节码可以看出,static变量和static块的相对位置不影响加载顺序,即先加载static变量,再执行static块中的内容,下面让我们看下static块的加载顺序。

static <clinit>()V   L0    LINENUMBER 5 L0    BIPUSH 9    PUTSTATIC p1/Test.a : I   L1    LINENUMBER 7 L1    ICONST_4    PUTSTATIC p1/Test.a : I   L2    LINENUMBER 3 L2    RETURN    MAXSTACK = 1    MAXLOCALS = 0

由字节码可知,代码中存在多个static块的时候(static int a = 4;和static int a;static{a = 4}的字节码完全相同,童鞋们自行实验),static块的加载顺序和代码的摆放顺序完全一致。下面给出本质完全相同的代码和字节码。

public class Test {static{a = 9;a = 4;}static int a;public static void main(String[] args) {System.out.println(a);}}

字节码如下

// class version 49.0 (49)// access flags 0x21public class p1/Test {  // compiled from: Test.java  // access flags 0x8  static I a  // access flags 0x8  static <clinit>()V   L0    LINENUMBER 5 L0    BIPUSH 9    PUTSTATIC p1/Test.a : I   L1    LINENUMBER 6 L1    ICONST_4    PUTSTATIC p1/Test.a : I   L2    LINENUMBER 3 L2    RETURN    MAXSTACK = 1    MAXLOCALS = 0  // access flags 0x1  public <init>()V   L0    LINENUMBER 3 L0    ALOAD 0    INVOKESPECIAL java/lang/Object.<init>()V    RETURN   L1    LOCALVARIABLE this Lp1/Test; L0 L1 0    MAXSTACK = 1    MAXLOCALS = 1  // access flags 0x9  public static main([Ljava/lang/String;)V   L0    LINENUMBER 10 L0    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;    GETSTATIC p1/Test.a : I    INVOKEVIRTUAL java/io/PrintStream.println(I)V   L1    LINENUMBER 11 L1    RETURN   L2    LOCALVARIABLE args [Ljava/lang/String; L0 L2 0    MAXSTACK = 2    MAXLOCALS = 1}

6.构造函数不可能是静态的,因为构造函数是和对象相关的,而static是和类直接关联的,所以不能混淆。

7.to be end...



原创粉丝点击