`
youlong699
  • 浏览: 21782 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

static static final 与 static 语句块

 
阅读更多

 

bluedavy 的一篇博客展开

· <clinit>

是由编译器收集static 字段、static 语句块生成的静态初始化方法, 虚拟机在初始化类的时候负责执行,并且父类先于子类;jvm负责加锁同步多个企图并发初始化一个类的调用 。

正是由于这里对<clinit>的隐含加锁,导致了B大帖子里死锁现象的产生。

类的初始化问题可以见《深入jvm虚拟机》 p187

通过javap -c 找不到<clinit> ,但是能看到static{}块,实际上它就是<clint> , 见R大帖子

· static  字段与 static final 字段

前者是类级别的, 后者会被搞到常量池, jvm级别的,因此访问一个类的static final 字段并不会导致该类的加载。

验证方法:

public class A{
    public static void main(String[] args){
        System.out.println(B.NAME);
        System.out.println(B.CONST_NAME);
    }
}

public class B{
    public static String NAME="bluedavy";
    public static final String CONST_NAME = "bluedavy_const";
    static{
        System.out.println("hellojava");
    }
}

javap -verbose A :

	Compiled from "A.java"
public class A extends java.lang.Object
  SourceFile: "A.java"
  minor version: 0
  major version: 50
  Constant pool:
const #1 = Method	#7.#16;	//  java/lang/Object."<init>":()V
const #2 = Field	#17.#18;	//  java/lang/System.out:Ljava/io/PrintStream;
const #3 = Field	#19.#20;	//  B.NAME:Ljava/lang/String;
const #4 = Method	#21.#22;	//  java/io/PrintStream.println:(Ljava/lang/String;)V
const #5 = String	#23;	//  bluedavy_const
const #6 = class	#24;	//  A
const #7 = class	#25;	//  java/lang/Object
const #8 = Asciz	<init>;
const #9 = Asciz	()V;
const #10 = Asciz	Code;
const #11 = Asciz	LineNumberTable;
const #12 = Asciz	main;
const #13 = Asciz	([Ljava/lang/String;)V;
const #14 = Asciz	SourceFile;
const #15 = Asciz	A.java;
const #16 = NameAndType	#8:#9;//  "<init>":()V
const #17 = class	#26;	//  java/lang/System
const #18 = NameAndType	#27:#28;//  out:Ljava/io/PrintStream;
const #19 = class	#29;	//  B
const #20 = NameAndType	#30:#31;//  NAME:Ljava/lang/String;
const #21 = class	#32;	//  java/io/PrintStream
const #22 = NameAndType	#33:#34;//  println:(Ljava/lang/String;)V
const #23 = Asciz	bluedavy_const;
const #24 = Asciz	A;
const #25 = Asciz	java/lang/Object;
const #26 = Asciz	java/lang/System;
const #27 = Asciz	out;
const #28 = Asciz	Ljava/io/PrintStream;;
const #29 = Asciz	B;
const #30 = Asciz	NAME;
const #31 = Asciz	Ljava/lang/String;;
const #32 = Asciz	java/io/PrintStream;
const #33 = Asciz	println;
const #34 = Asciz	(Ljava/lang/String;)V;

{
public A();
  Code:
   Stack=1, Locals=1, Args_size=1
   0:	aload_0
   1:	invokespecial	#1; //Method java/lang/Object."<init>":()V
   4:	return
  LineNumberTable: 
   line 1: 0


public static void main(java.lang.String[]);
  Code:
   Stack=2, Locals=1, Args_size=1
   0:	getstatic	#2; //Field java/lang/System.out:Ljava/io/PrintStream;
   3:	getstatic	#3; //Field B.NAME:Ljava/lang/String;
   6:	invokevirtual	#4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   9:	getstatic	#2; //Field java/lang/System.out:Ljava/io/PrintStream;
   12:	ldc	#5; //String bluedavy_const
   14:	invokevirtual	#4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   17:	return
  LineNumberTable: 
   line 3: 0
   line 4: 9
   line 5: 17
}

javap -verbose B:

Compiled from "B.java"
public class B extends java.lang.Object
  SourceFile: "B.java"
  minor version: 0
  major version: 50
  Constant pool:
const #1 = Method	#8.#21;	//  java/lang/Object."<init>":()V
const #2 = String	#22;	//  bluedavy
const #3 = Field	#7.#23;	//  B.NAME:Ljava/lang/String;
const #4 = Field	#24.#25;	//  java/lang/System.out:Ljava/io/PrintStream;
const #5 = String	#26;	//  hellojava
const #6 = Method	#27.#28;	//  java/io/PrintStream.println:(Ljava/lang/String;)V
const #7 = class	#29;	//  B
const #8 = class	#30;	//  java/lang/Object
const #9 = Asciz	NAME;
const #10 = Asciz	Ljava/lang/String;;
const #11 = Asciz	CONST_NAME;
const #12 = Asciz	ConstantValue;
const #13 = String	#31;	//  bluedavy_const
const #14 = Asciz	<init>;
const #15 = Asciz	()V;
const #16 = Asciz	Code;
const #17 = Asciz	LineNumberTable;
const #18 = Asciz	<clinit>;
const #19 = Asciz	SourceFile;
const #20 = Asciz	B.java;
const #21 = NameAndType	#14:#15;//  "<init>":()V
const #22 = Asciz	bluedavy;
const #23 = NameAndType	#9:#10;//  NAME:Ljava/lang/String;
const #24 = class	#32;	//  java/lang/System
const #25 = NameAndType	#33:#34;//  out:Ljava/io/PrintStream;
const #26 = Asciz	hellojava;
const #27 = class	#35;	//  java/io/PrintStream
const #28 = NameAndType	#36:#37;//  println:(Ljava/lang/String;)V
const #29 = Asciz	B;
const #30 = Asciz	java/lang/Object;
const #31 = Asciz	bluedavy_const;
const #32 = Asciz	java/lang/System;
const #33 = Asciz	out;
const #34 = Asciz	Ljava/io/PrintStream;;
const #35 = Asciz	java/io/PrintStream;
const #36 = Asciz	println;
const #37 = Asciz	(Ljava/lang/String;)V;

{
public static java.lang.String NAME;

public static final java.lang.String CONST_NAME;
  Constant value: String bluedavy_const
public B();
  Code:
   Stack=1, Locals=1, Args_size=1
   0:	aload_0
   1:	invokespecial	#1; //Method java/lang/Object."<init>":()V
   4:	return
  LineNumberTable: 
   line 1: 0


static {};
  Code:
   Stack=2, Locals=0, Args_size=0
   0:	ldc	#2; //String bluedavy
   2:	putstatic	#3; //Field NAME:Ljava/lang/String;
   5:	getstatic	#4; //Field java/lang/System.out:Ljava/io/PrintStream;
   8:	ldc	#5; //String hellojava
   10:	invokevirtual	#6; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   13:	return
  LineNumberTable: 
   line 2: 0
   line 5: 5
   line 6: 13


}


 

从A的常量池可以看到

  1. const #5 = String   #23;    //  bluedavy_const 
  2. const #23 = Asciz    bluedavy_const;
bluedavy_const 已经直接搞到了A的常量池里, 脱离了B ;
而对比A的代码:
3:    getstatic    #3; //Field B.NAME:Ljava/lang/String;
12:    ldc    #5; //String bluedavy_const
也可以看到, 使用两个常量的不同
另外,可以在运行代码时加上-verbose:class 打印类加载信息,如果去掉
 System.out.println(B.NAME);
仅保留
 System.out.println(B.CONST_NAME);
是不会导致B.class加载的。
分享到:
评论

相关推荐

    类的使用,学习,小结 java定义一个学生类

    java定义一个学生类 class A{ private double a; A(){} ... [public /protected /private /static /final /abstract] 返回值类型 方法名字(参数){ //如果返回值类型不是void,必须有return语句 } }

    Java基础知识点.html

    Date类 自动拆箱和自动装箱 Arrays 类和接口的关系 内部类 成员内部类 局部内部类 匿名内部类 抽象类 接口 多态 封装 类和对象 方法 StringBuilder类 String类 static for循环 final 权限修饰符 跳转控制语句 while...

    Java问题宝典2012版

    1. Java基础部分 7 1、一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 8 2、Java有没有goto? 8 3、说说&和&&的区别。 8 4、在JAVA中如何跳出当前的多重...在try块中可以抛出异常吗? 32 .... ....

    java基础核心总结归纳---参考手册--心得手册-学习资料-总结经验

    与 Exception 有关的 Java 关键字 19 什么是 Error 20 内部类 20 集合 20 ArrayList 21 Vector 21 LinkedList 21 Stack 21 HashSet 22 TreeSet 22 LinkedHashSet 22 HashMap 23 集合实现类特征图 23 泛形 23 反射 24...

    java程序员必知的

    第一,谈谈final, finally, finalize的区别。  final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。... &是位运算符,表示按位与运算,&&是逻辑运算符,表示逻辑与(and). 

    北航网络教育JAVA语言与面向对象程序设计单选题及答案.doc

    JAVA语言与面向对象程序设计单选题 applet的主要方法 在Java Applet程序用户自定义的Applet子类中,一般需要重载父类的( )方法来完成主类实例的初始化工作。 A.A. start( ) B. B. stop( ) C. C. init( ) D. D. paint...

    Java 面试题问与答:编译时与运行时

    在开发和设计的时候,我们需要考虑编译时,运行时... static final int number1 = 5; static final int number2 = 6; static int number3 = 5; static int number4= 6; public static void main(String[ ] args

    Java监控u盘插入

    private static final String[] arr = new String[] {"C", "D", "E", "F", "G", "H", "I", "J","K","L"}; public static void main(String[] args){ init(); check(); System.out.println("检测到U盘"); /...

    网络及数据库编程设计.doc

    " " " "/** " "* 数据库连接和关闭工具类 " "* @author ruochen " "* @version 1.0 " "*/ " "public class DBConfig { " "/** 定义数据库驱动类名称 */ " "private static final String JDBC_DRIVER = " "...

    java基础学习知识整理资料很完善,还附带源码

    Java多态和接口 Java类与对象基础 Java集合框架(1) Java循环语句 Java常用类 Java数组及排序 Java异常处理 Java封装与继承 Java文件处理(IO)1 Java static-final及常用类x

    android数据库

    private static final String DB_CREATE = "create table " + DB_TABLE + " (" + KEY_ID + " integer primary key autoincrement, " + KEY_NAME + " text not null, " + KEY_AGE + " integer," + KEY_HEIGHT + ...

    【05-面向对象(下)】

    如果代码块只有包含一条语句,Lambda表达式允许省略代码块的花括号,如果省略了代码块的花括 号,这条语句不要用花括号表示语句结束。Lambda代码块只有一条return语句,甚至可以省略return关键字。 Lambda表达式...

    北交《JAVA语言设计》在线作业二.docx

    以上都不对 B.static C.final D.abstract 答案:C 3.数组的大小在创建以后( )。 A.有些可以改变 B.可以改变 C.使用new方法可以改变 D.不能改变 答案:D 4.main方法是java Application 程序执行的入口点,关于main方法的...

    JAVA语言程序设计【高清版】.pdf

    77 5.5.1 static 77 5.5.2 final和abstract 79 5.5.3 this和super 84 5.6 方法重写 86 5.6.1 方法重写概述 86 5.6.2 应用重写的规则 89 5.6.3 调用父类构造方法 89 5.7 接口 90 5.7.1 多重继承中的...

    【04-面向对象(上)】

    •用static修饰的初始化块为静态初始化块,由于是静态的,所以是属于类,当类加载时,就执行静态初始化块 ,  但执行一个子类时,最先执行其最顶层父类的静态初始化, •初始化块是属于实例 的。只要创建一次...

    贪吃蛇java课程设计--贪吃蛇程序设计.doc

    " "为了对所学的课程进行加深理解,熟练的掌握JAVA的语法与语句,对其进行应用。" "通过此次课程设计,巩固所学Java语言基本知识,增进Java语言编辑基本功,掌握" "JDK、JCreator等开发工具的运用,拓宽常用类库的...

    MySQLDBStatement:Java IntelliJ IDEA数据库语句

    public class Main {public static final String URL =“ jdbc:mysql:// localhost:3306 / newmysqldb”; public static final String USERNAME =“ root”; public static final String PASSWORD =“ 2015”; ...

    Android 安卓数据库 sqlite android自带数据库使用

    Android 安卓数据库 Android是有自带的数据库的 原生数据库 ... public static final String sql = sql语句; public static final String sql1 = sql语句; public MySQLiteHelper(@Nullable Context c

Global site tag (gtag.js) - Google Analytics