由 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的常量池可以看到
- const #5 = String #23; // bluedavy_const
- const #23 = Asciz bluedavy_const;
而对比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定义一个学生类 class A{ private double a; A(){} ... [public /protected /private /static /final /abstract] 返回值类型 方法名字(参数){ //如果返回值类型不是void,必须有return语句 } }
Date类 自动拆箱和自动装箱 Arrays 类和接口的关系 内部类 成员内部类 局部内部类 匿名内部类 抽象类 接口 多态 封装 类和对象 方法 StringBuilder类 String类 static for循环 final 权限修饰符 跳转控制语句 while...
1. Java基础部分 7 1、一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 8 2、Java有没有goto? 8 3、说说&和&&的区别。 8 4、在JAVA中如何跳出当前的多重...在try块中可以抛出异常吗? 32 .... ....
与 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...
第一,谈谈final, finally, finalize的区别。 final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。... &是位运算符,表示按位与运算,&&是逻辑运算符,表示逻辑与(and).
JAVA语言与面向对象程序设计单选题 applet的主要方法 在Java Applet程序用户自定义的Applet子类中,一般需要重载父类的( )方法来完成主类实例的初始化工作。 A.A. start( ) B. B. stop( ) C. C. init( ) D. D. paint...
在开发和设计的时候,我们需要考虑编译时,运行时... static final int number1 = 5; static final int number2 = 6; static int number3 = 5; static int number4= 6; public static void main(String[ ] args
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盘"); /...
" " " "/** " "* 数据库连接和关闭工具类 " "* @author ruochen " "* @version 1.0 " "*/ " "public class DBConfig { " "/** 定义数据库驱动类名称 */ " "private static final String JDBC_DRIVER = " "...
Java多态和接口 Java类与对象基础 Java集合框架(1) Java循环语句 Java常用类 Java数组及排序 Java异常处理 Java封装与继承 Java文件处理(IO)1 Java static-final及常用类x
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 + ...
如果代码块只有包含一条语句,Lambda表达式允许省略代码块的花括号,如果省略了代码块的花括 号,这条语句不要用花括号表示语句结束。Lambda代码块只有一条return语句,甚至可以省略return关键字。 Lambda表达式...
以上都不对 B.static C.final D.abstract 答案:C 3.数组的大小在创建以后( )。 A.有些可以改变 B.可以改变 C.使用new方法可以改变 D.不能改变 答案:D 4.main方法是java Application 程序执行的入口点,关于main方法的...
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 多重继承中的...
•用static修饰的初始化块为静态初始化块,由于是静态的,所以是属于类,当类加载时,就执行静态初始化块 , 但执行一个子类时,最先执行其最顶层父类的静态初始化, •初始化块是属于实例 的。只要创建一次...
" "为了对所学的课程进行加深理解,熟练的掌握JAVA的语法与语句,对其进行应用。" "通过此次课程设计,巩固所学Java语言基本知识,增进Java语言编辑基本功,掌握" "JDK、JCreator等开发工具的运用,拓宽常用类库的...
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 安卓数据库 Android是有自带的数据库的 原生数据库 ... public static final String sql = sql语句; public static final String sql1 = sql语句; public MySQLiteHelper(@Nullable Context c