public class Evis { static Evis instance = new Evis(); static final String START = new String("START") + " " + Evis.END; static final String END = "END"; static String start = new String("start") + " " + Evis.end; static String end = "end"; final String _START = new String("_START") + " " + this._END; final String _END = "_END"; String _start = new String("_start") + " " + this._end; String _end = "_end"; String MESSAGE; String message; String _MESSAGE; String _message;
public Evis() { MESSAGE = "START = " + START + ", END = " + END; this.message = "start = " + start + ", end = " + end; _MESSAGE = "_START = " + _START + ", _END = " + _END; this._message = "_start = " + _start + ", _end = " + _end; } public void show() { System.out.println(); System.out.println(this.MESSAGE); System.out.println(this.message); System.out.println(this._MESSAGE); System.out.println(this._message); } public static void main(String[] args) { //递归的初始化尝试会直接被忽略掉 Evis.instance.show(); } }
输出为:
START = null, END = END
start = null, end = null
_START = _START _END, _END = _END
_start = _start null, _end = _end
* 递归的初始化尝试会直接被忽略掉
* 类加载和实例初始化时,分配空间并设置缺省值时,会将final变量中使用常量或常量表达式赋值的变量
直接设置为常量值而不是缺省值。
* 类加载初始化时:
static final 类型的域在未初始化之前被引用,只有在其初始化表达式是常量或常量表达式时才是常量值,
否则为缺省值。
static 类型的域在未初始化之前被引用,为缺省值。
通常在声明之前直接引用会引发编译错误,可以用 ClassName.引用。
* 类实例初始化时:
final 类型的实例域在未初始化之前被引用,只有在其初始化表达式是常量或常量表达式时才是常量值,
否则为缺省值。
普通类型的实例域在未初始化之前被引用,为缺省值。
通常在声明之前直接引用会引发编译错误,可以用this.引用。
public enum RomanNumeral { I(1), V(5), X(10), L(50), C(100), D(500), M(1000); private static Map<Integer, RomanNumeral> map = new LinkedHashMap<Integer, RomanNumeral>(); public final int val; RomanNumeral(int val) { this.val = val; storeInMap(); } private void storeInMap() { map.put(val, this); } public static RomanNumeral fromInt(int val) { return map.get(val); } public static void main(String[] args) { int sum = 0; for (int i = 0; i < 1000; i++) { if (fromInt(i) != null) { sum += i; } } System.out.println(sum); } }
输出为:
Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: java.lang.NullPointerException
at com.jaeson.javastudy.thinkinjava.RomanNumeral.storeInMap(RomanNumeral.java:18)
at com.jaeson.javastudy.thinkinjava.RomanNumeral.<init>(RomanNumeral.java:14)
at com.jaeson.javastudy.thinkinjava.RomanNumeral.<clinit>(RomanNumeral.java:8)
* 类加载过程(静态属性、静态方法声明-----静态属性赋值、静态块)
* 实例化过程(普通属性、普通方法声明-----普通属性赋值、构造块----构造方法中的代码)
* 如果在类加载过程中调用了实例化过程(如new了本类对象),则会暂停类加载过程先执行实例化过程,
执行完毕再回到类加载过程
相关推荐
java JVM 类加载-初始化 过程
本文将详细探讨Java中类的初始化过程及其顺序,并通过具体的代码示例来帮助理解这一过程。 #### 二、基础知识 1. **静态成员变量(Static Fields)**:在类加载时初始化。 2. **实例成员变量(Instance Fields)**...
当创建一个子类实例时,初始化过程遵循以下步骤: 1. **静态初始化**:首先,执行父类的静态初始化块,然后执行子类的静态初始化块。静态初始化块用于初始化类级别的静态变量,它们只在类加载时执行一次。 2. **...
Java类加载初始化的过程是Java编程语言中一个重要的概念,它决定了Java类的加载和初始化顺序。在Java中,类的加载是通过类加载器(ClassLoader)来实现的。类加载器会将类的字节码文件(.class)加载到Java虚拟机...
这个顺序表明,无论类之间的继承关系如何,初始化顺序始终是:静态变量和静态初始化块先于非静态成员。在创建对象时,父类的初始化先于子类。这是Java语言规范所规定的,确保在子类访问父类的静态或非静态成员时,...
- 当多个线程同时尝试初始化同一个类时,Java保证只会执行一次类的初始化过程。这是由JVM的同步机制保证的,避免了数据竞争的问题。 5. **接口初始化**: - 接口没有实例变量,所以不存在实例初始化阶段。接口的...
在本文中,我们讨论了 Java 类加载器中的静态变量初始化机制,了解了静态变量的初始化顺序和类加载器的生命周期。通过对静态变量初始化机制的理解,我们可以更好地掌握 Java 语言的基础知识,并更好地应用 Java 语言...
总之,Java代码的初始化顺序是类加载的必然过程,涉及到静态和实例初始化块、构造函数、成员变量初始化以及继承关系的影响。这个demo是学习和理解这些概念的重要工具,通过实际操作可以加深对Java内存管理和对象生命...
Java虚拟机JVM类加载初始化是Java程序运行过程中的关键环节,它负责将类的字节码文件加载到内存中并进行相应的处理,以便程序能够正确执行。在Java中,类加载器(Classloader)扮演着核心角色。下面将详细讨论类加载...
3. **初始化**:执行类构造器`()`方法,为类变量赋初始值。 #### 三、类与类加载器的关系 类加载器对于确定类在JVM中的唯一性至关重要。两个类只有当它们来自相同的类加载器时才被认为是相同类的不同实例。这意味...
Java类加载连接和初始化是Java虚拟机(JVM)中一个非常重要的机制,它们共同完成了类从加载到初始化的整个过程。下面我们将详细介绍Java类加载连接和初始化原理分析。 一、类加载 类加载是Java虚拟机将类从.class...
它不仅管理类的生命周期,还确保了类的正确加载和初始化,是Java动态特性的基石。 #### 类加载器的工作原理 Java类加载器遵循按需加载原则,即只有当应用程序真正需要使用某个类时,类加载器才会去加载它。这一...
总之,深入理解Java的ClassLoader机制和类变量初始化顺序是提升Java编程技能的重要步骤。通过学习这些知识点,开发者可以更好地优化代码、设计更健壮的系统,并解决与类加载和初始化相关的复杂问题。
总之,理解并有效地使用静态和对象初始化块是Java开发中的关键技能,它们可以帮助我们更好地控制类和对象的初始化过程,确保代码的高效性和正确性。在实际编程中,我们应该根据需求谨慎选择合适的初始化策略,以优化...
通过以上分析,我们可以看到Java虚拟机的类加载初始化过程是一个复杂但有序的过程。理解这些基本概念对于编写高效、可靠的Java应用程序至关重要。希望本文能够帮助您更好地掌握Java虚拟机的核心机制之一:类加载初始...
类加载的过程主要分为三个阶段:加载(Loading)、连接(Linking)和初始化(Initialization)。 1. **加载**(Loading): - 类加载器查找并加载类的二进制流。 - 创建`java.lang.Class`对象,代表这个类。 2. ...
我们可以在业务层自己控制 A 和 B 的初始化顺序,在 A 中设置一个“是否初始化的”标记,B 初始化前检测 A 是否得以初始化,如果没有则调用 A 的初始化方法,所谓的 check-and-act。 这种方法的优点是可以做到 lazy...