首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >递归初始化:在我访问类字段时不调用静态初始化程序

递归初始化:在我访问类字段时不调用静态初始化程序
EN

Stack Overflow用户
提问于 2015-05-09 08:52:16
回答 1查看 403关注 0票数 3

理解如何加载类和调用静态初始化程序

静态初始化程序块的顺序是什么?

所以,我只是想确认一下-

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class OOMErrorB extends OOMErrorA {
    public static int c = 10;

    static {
        System.out.println("Loading static B " + c);
        System.out.println(OOMErrorA.a);
    }

    public static void main(String[] args) {
        new OOMErrorB();
    }
}

父类是-

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class OOMErrorA {
    public static int a = 20;

    static {
        a = a+ OOMErrorB.c;
        System.out.println("OOMErrorB.c " + OOMErrorB.c);
        System.out.println("loading OOMErrorA.a " + a);
    }
}

现在输出的主要方法是B-

**

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
OOMErrorB.c 0
loading OOMErrorA.a 20
Loading static B 10
20

**

我可以理解,首先它是加载A类,因为它是超类,并且调用它是静态初始化器,

现在,由于我在OOMErrorA的静态块中访问OOMErrorB.c,所以它应该加载和调用OOMErrorB的静态初始化器。所以,OOMErrorB.c应该是10而不是0。

我知道如何装载和初始化一个类-

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1) Class and gets loaded and variables are initialized to default values like for int - 0, Object - null.
2) Class field are initialized to specified values.
3) Static block gets called .

在我的程序中,我可以看到类OOMErrorB被加载(步骤1),但是步骤2和步骤3没有执行。

然而,根据链路上公认的答案,它应该调用OOMErrorB的静态初始化器。

所以它最终应该是循环依赖的?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-05-09 08:56:53

当访问OOMErrorB.c时,没有加载OOMErrorB,因为它已经在加载过程中(当JVM最初加载它以调用main方法时)。一旦在JVM中加载了一个类,它就不会再加载了。因此,不存在循环依赖关系:获取OOMErrorB的静态成员c,此时仍未初始化该成员。

您可以检查有关类初始化的本节来自Java语言规范

因为Java编程语言是多线程的,所以类或接口的初始化需要仔细的同步,因为其他一些线程可能同时尝试初始化同一个类或接口。还有可能递归地请求类或接口的初始化,作为该类或接口初始化的一部分;例如,A类中的变量初始化器可能会调用不相关的B类的方法,而后者又可能调用A类的方法。Java虚拟机的实现负责通过以下过程处理同步和递归初始化。

JVM有其正确的方法锁定类的初始化,以防止递归初始化。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30142611

复制
相关文章
Java类的初始化顺序_java静态类初始化顺序
类变量先分配内存并且赋值为默认值,再进行初始化。类变量和对象变量初始化顺序都为从上到下初始化,有变量初始化,代码块初始化,构造器初始化
全栈程序员站长
2022/09/22
7360
构造方法、类的初始化块以及类字段的初始化顺序
类的初始化块不接收任何的参数,而且只要一创建类的对象,它们就会被执行。因此,适合于封装那些“对象创建时必须执行的代码”。
CN_Simo
2022/05/10
5440
为什么应该尽可能避免在静态构造函数中初始化静态字段?
C#具有一个默认开启的代码分析规则:[CA1810]Initialize reference type static fields inline,推荐我们以内联的方式初始化静态字段,而不是将初始化放在静态构造函数中。
蒋金楠
2023/07/21
1910
Java中的静态初始化和非静态初始化
Java与C++的一个不同之处在于,Java不仅有构造函数,还有一个“初始化块”(Initialization Block)的概念。Java中的初始化块在创建Java对象时隐式执行,并且是在构造函数之前执行。
Tyan
2019/05/25
2.8K0
java类加载和初始化_java静态变量什么时候初始化
将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后生成一个代表这个类的java.lang.class对象。
全栈程序员站长
2022/09/22
5060
确保初始化静态成员
在开发时我们习惯在创将某个实例之前先把静态成员变量初始化好,具体做法是通过静态初始化语句以及静态构造函数。静态构造函数在 c# 是比较特殊的函数,它会在第一次访问所在类定义的其他方法、变量和属性之前执行,一般我们用它来初始化静态变量、实现单例模式以及执行其他一些需要在访问其他必要的工作。如果静态字段初始化工作较为复杂或者是初始化开销很大的话,那么我们可以使用 Lazy 机制将初始化工作推迟在第一次访问该字段的时候再去执行。 在 C# 中比较常见的静态初始化语句是实现单例模式,开发人员可以将实例级别的构造函数设为 private ,并添加静态初始化语句并在其中调用这私有的实力构造函数。我们来看一个例子,具体来看看怎么实现单例模式:
喵叔
2020/09/08
8620
【Kotlin】属性 与 幕后字段 ( 属性声明 | 属性初始化器 | 属性访问器 | field 属性幕后字段 | lateinit 延迟初始化属性 )
④ 属性幕后字段 : 属性的实际值存储在 field 幕后字段中 , 只能在属性访问器中可以使用 field 获取该值 ;
韩曙亮
2023/03/27
1.4K0
【Kotlin】属性 与 幕后字段 ( 属性声明 | 属性初始化器 | 属性访问器 | field 属性幕后字段 | lateinit 延迟初始化属性 )
Java中类的初始化过程:(静态成员变量,静态代码块,普通成员变量,代码块初始化顺序)
初始化过程是这样的: 1.首先,初始化父类中的静态成员变量和静态代码块,按照在程序中出现的顺序初始化; 2.然后,初始化子类中的静态成员变量和静态代码块,按照在程序中出现的顺序初始化; 3.其次,初始化父类的普通成员变量和代码块,在执行父类的构造方法; 4.最后,初始化子类的普通成员变量和代码块,在执行子类的构造方法;
小尘要自信
2023/10/10
5160
python中子类调用父类的初始化方法
http://bestchenwu.iteye.com/blog/1044848
py3study
2020/01/09
2.2K0
CA1810:以内联方式初始化引用类型的静态字段
当一个类型声明显式静态构造函数时,实时 (JIT) 编译器会向该类型的每个静态方法和实例构造函数中添加一项检查,以确保之前已调用该静态构造函数。 访问任何静态成员或创建该类型的实例时,将触发静态初始化。 但是,如果声明一个类型的变量,但不使用它,则不会触发静态初始化;这在初始化会更改全局状态的情况下非常重要。
呆呆
2022/02/19
6300
C++使用初始化列表的方式来初始化字段
明白了上述用法以后,Android Recovery源代码里面也有类似的案例。下面这个是Recovery的一个构造函数,代码位于:screen_ui.cpp,它的类的实现在screen_ui.h。如下这个ScreenRecoveryUI类,这个类是继承于RecoveryUI类的,这个文件在screen_ui.h
杨源鑫
2019/07/12
1.3K0
「V8 9.1」新增类静态初始化代码块
如果你用过 Java ,那你一定对静态初始化代码块不会感到陌生, JavaScript 预计会在 v8 9.1 版本支持这个特性。
ConardLi
2021/04/07
5800
「V8 9.1」新增类静态初始化代码块
python类的初始化方法_python初始化列表
在scikit-learn基础上系统结合数学和编程的角度学习了机器学习后(我的github:https://github.com/wwcom614/machine-learning),意犹未尽,打算再借势学习下深度学习TensorFlow。无奈安装之后遇到了这个问题,耽误了几个小时才得以解决。
全栈程序员站长
2022/09/27
1K0
数据的初始化与访问
Java中的数组必须先初始化,然后才能使用。所谓初始化:就是为数组中的数组元素分配内存空间,并为每个数组元素赋值。
星哥玩云
2022/09/14
3450
数据的初始化与访问
java 初始化基类
在使用继承过程中,需要先声明新类与旧类相似,用关键字 extends实现 package javahaonan; import static javahaonan.Print.*; class Cleanser{ private String s ="Cleanser" ; public void append(String a) {s+=a;} public void dilute() {append("dilute()" );} public void
葫芦
2019/04/17
5970
java类初始化顺序
java代码块 静态代码块:用staitc声明,jvm加载类时执行,仅执行一次 构造代码块:类中直接用{}定义,每一次创建对象时执行。 执行顺序优先级:静态块,main(),构造块,构造方法。 构造函数 创建对象时调用 一般用于给对象初始化 一个对象建立,构造函数执行一次 构造代码块 用来给对象初始化 对象建立时运行构造代码块,优先于构造函数 构造代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化。因为构造函数是可以多个的,运行哪个构造函数就会建立什么样的对象,但无论建立哪个对象,都会先执行相
leobhao
2022/06/28
8582
当面试官问我Mybatis初始化原理时,我笑了
对于任何框架而言,在使用前都要进行一系列的初始化,MyBatis也不例外。本章将通过以下几点详细介绍MyBatis的初始化过程。
Bug开发工程师
2018/12/29
7420
点击加载更多

相似问题

Python通过调用递归静态方法初始化类变量

24

如何初始化递归内部静态类?

26

静态类-延迟字段初始化

21

调用类方法初始化静态类

14

调用静态方法时未初始化的静态Java字段

14
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文