java中构造函数调用时机,“构造函数调用必须是Java中构造函数中的第一个语句”问题...

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:

Why does this() and super() have to be the first statement in a constructor?

我想在爪哇有一个构造函数链。例如,使用第一个构造函数,我有一个字符串作为参数,并在从参数字符串创建对象时调用第二个构造函数。

public class IMethodFinder {

public IMethodFinder(String projectName, String methodName,

int numberOfParameters) {

IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);

IJavaProject javaProject = JavaCore.create(project);

this(javaProject, methodName, numberOfParameters);

}

public IMethodFinder(IJavaProject javaProject, String methodName,

int numberOfParameters) {

...

}

}

但是,我得到一个错误"constructor call must be the first statement in a constructor"错误。

e09705912fd930adf1b99b9b8910988e.png

我编写了一个在两个构造函数之间共享的公共代码,但我不确定这是绕过这个问题的唯一解决方案。

public class IMethodFinder {

public IMethodFinder(IJavaProject javaProject, String methodName,

int numberOfParameters) {

dosomething(javaProject, methodName, numberOfParameters);

}

public IMethodFinder(String projectName, String methodName,

int numberOfParameters) {

IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);

IJavaProject javaProject = JavaCore.create(project);

dosomething(javaProject, methodName, numberOfParameters);

}

private void dosomething(IJavaProject javaProject, String methodName,

int numberOfParameters)

{

...

}

}

为什么Java需要构造函数调用作为第一个语句?这个要求背后的想法是什么?

我的案例是什么Java约定?调用公共方法是一种好方法吗?

是的,从构造函数调用init()函数很常见。

您可以将第一个构造函数的主体重写为:this(JavaCore.create(ResourcesPlugin.getWorkspace().getRoot(‌​).getProject(project‌​Name)), methodName, numberOfParameters);。

没有什么内在的原因,为什么Java不能被扩展到允许在构造函数之前不访问EDCOX1×4的语句。但是,这会增加语言的复杂性,并在使用时模糊代码(特别是当您认为调用可能是隐式的时候)。

通常,您希望尽可能简单地保留构造函数。init()方法是个坏主意,因为它们阻止了final的使用。似乎代码正在访问可变静态,这是一个非常糟糕的主意。

对于您的特定代码,您可以编写:

public IMethodFinder(String projectName, String methodName,

int numberOfParameters) {

this(

JavaCore.create(

ResourcesPlugin.getWorkspace().getRoot().getProject(projectName)

),

methodName,

numberOfParameters

);

}

更一般的方法是在对构造函数的调用中调用静态方法:

public class IMethodFinder {

public IMethodFinder(String projectName, String methodName,

int numberOfParameters) {

this(createProject(projectName), methodName, numberOfParameters);

}

public IMethodFinder(IJavaProject javaProject, String methodName,

int numberOfParameters) {

...

}

private static IJavaProject createProject(String projectName) {

IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);

IJavaProject javaProject = JavaCore.create(project);

return javaProject;

}

}

编辑:2018年3月:在消息记录:构造和验证中,Oracle建议删除此限制(但与C不同的是,在构造链接之前,this将绝对未被分配(du)。

Historically, this() or super() must be first in a constructor. This

restriction was never popular, and perceived as arbitrary. There were

a number of subtle reasons, including the verification of

invokespecial, that contributed to this restriction. Over the years,

we've addressed these at the VM level, to the point where it becomes

practical to consider lifting this restriction, not just for records,

but for all constructors.

+ 1,"没有Java无法扩展的内在原因,允许在构造函数之前不访问Java的语句"。

解决方案1:您的构造器应该有一个更好的流程,以避免使用通用的init。通常情况下,一个构造函数会更基本,并构造一个完整的有效对象,然后外部构造函数可以修饰这个对象。

解决方案2:使用静态工厂方法通常是很好的实践,例如,可以在这里处理您需要的预处理。这看起来是这个模式的一个很好的用例。

解决方案3:与普通的init方法不同,只有静态方法可以为您进行独立的预处理。如myField = processInputField(myField)。普通的init方法在最后一个字段中的作用非常差,这是它们不好实践的一个更强有力的原因——本质上,是的,施工人员应该完成施工的全部工作。

看到你第一个问题的答案对于您的第二个问题-是的,对这些情况使用某种init()方法是相对公认的。

看看这个。它可能有助于理解Java的安全调用。

构造函数调用必须是构造函数中的第一条语句

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值