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 0x21
public 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 0x21
public 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...