当前位置: 首页 > 面试题库 >

当我添加“ this”时,递归初始化器可以工作吗?

吴经略
2023-03-14
问题内容

编译失败(出现illegal forward reference错误),正如人们期望的那样:

class test {
    int x = x + 42;
}

但这有效:

class test {
    int x = this.x + 42;
}

这是怎么回事?在后一种情况下分配什么?


问题答案:

摘要:两个初始化程序都访问一个尚未初始化的字段(因此,其默认值为零)。由于这很可能是编程错误,因此该语言禁止了这种访问的某些简单形式。但是,它不禁止使用更复杂的形式。

该行为符合JLS,特别是第8.3.2.3节。初始化期间对字段的使用限制

只有在成员声明是static类或接口的实例字段(分别为)C且满足以下所有条件的情况下,成员声明才需要以文本形式出现:

  • 使用情况发生在C的实例(分别static)的变量初始化程序中或C的实例(分别static)的初始化程序中。

  • 用法不在作业的左侧。

  • 用法是通过一个简单的名称。

  • C 是包含用法的最里面的类或接口。

第一个示例满足所有四个条件,因此无效。第二个示例不满足第三个条件(this.x不是简单的名称),因此可以。

事件的总体顺序如下:

  • 创建类的实例时,所有字段都将初始化为其类型的默认值。
  • 然后按文本顺序(从上到下)运行初始化程序。

因此,如果初始化程序引用的是稍后在类定义中出现的字段(或字段本身),它将看到该其他字段的默认值。这很可能是编程错误,因此第8.3.2.3节明确禁止。

例如,如果通过使用this.前向引用字段来绕过§8.3.2.3
,您将看到默认值(表示零int)。因此,以下内容定义明确,可以保证将其设置x42

class test {
    int x = this.x + 42;
}


 类似资料:
  • 问题内容: 我正在hibernate中编写一个函数以递归方式初始化对象的所有属性,以便加载整个对象图。 我有两个需要使用的复杂场景 1)自复合对象,例如类别和子类别… 2)复杂的对象图,其中有很多对象需要初始化才能使用。 问题是我不能使用急切的获取,因为我仅在特定情况下才需要整个对象图,而且我想拥有通用代码,因此不需要为对象编写HQL查询。 我为此写了一些代码, 但是它有一个问题,由于双向关系,它

  • 问题内容: 我想在WTForms的字段上添加一个占位符属性。我该怎么做? 上面的代码无效 如何添加具有值的占位符属性? 问题答案: 针对WTForms 2.1更新 从WTForms 2.1(2015年12月)开始,您现在可以通过使用字段构造函数的参数来设置呈现关键字。 因此该字段看起来像: 注意这是可能的;它确实开始弥合代码和表示之间的界限;所以明智地使用它! (旧答案,对于早于WTForms 2

  • 问题内容: 我想开发一个spring AOP功能,我们可以在spring bean初始化期间放置一个切入点/切入点,以便根据业务需要计算一些统计信息。我想知道是否可以使用spring AOP模块? 问题答案: 您可以使用以下组件来测量初始化时间: 但是这次不包括运行构造函数的时间。 但是,您可以在读取所有bean定义之后记录一下,然后运行所有bean构造函数。为此使用BeanFactoryPost

  • 我在想,是否可以使用对< code>this关键字的引用来初始化一个(引用类型)属性(当它的值为< code>null),而不使用构造函数。< br >在某些情况下,我不想使用构造函数来初始化属性,因此,如果没有人访问它,它的值将不会被创建。< br >此外,如果可能的话,我不喜欢在构造函数中将属性声明与其初始化分开。 一个典型的例子是MVVM模式编程的命令声明: 我不喜欢写三倍的成员的名字… 我

  • 问题内容: 我天真地尝试创建一个递归生成器。没用 这是我所做的: 我所得到的只是第一项。 有没有办法使这种代码起作用?本质上是在递归方案中将命令转移到以上级别吗? 问题答案: 尝试这个: 我应该指出,由于您的功能存在错误,因此无法使用。它可能应该包含不为空的支票,如下所示:

  • 问题内容: 我想用JLabel替换JButton,并且希望我的代码在单击JLabel时执行一些操作。 当我拥有JButton时,我使用动作侦听器来处理按钮的单击: 当我替换为时,我在Eclipse中收到以下错误消息: 对于JLabel类型,未定义方法addActionListener(ChipsListener) 但我确实知道应该可以将单击处理程序附加到JLabel。有人知道该怎么做吗? 问题答案