static简述

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...



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值