“构造函数调用必须是构造函数中的第一个语句”Java中的问题[重复]
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了“构造函数调用必须是构造函数中的第一个语句”Java中的问题[重复]相关的知识,希望对你有一定的参考价值。
可能重复: Why does this() and super() have to be the first statement in a constructor?
我想在Java中使用构造函数链。例如,对于第一个构造函数,我有一个字符串作为参数,并在我从参数字符串创建一个对象时调用第二个构造函数。
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) {
...
}
}
但是,我收到错误“构造函数调用必须是构造函数中的第一个语句”错误。
我制作了一个在两个构造函数之间共享的公共代码,但我不确定这是绕过该问题的唯一解决方案。
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的惯例?调用常用方法是一种好方法吗?
没有内在的原因可以解释为什么Java不能扩展为允许在构造函数之前不访问this
的语句。但是,这会增加语言的复杂性并在使用时模糊代码(特别是当您认为调用可能是隐含的时)。
通常,您希望保持构造函数尽可能简单。 init()
方法是一个坏主意,因为它们阻止使用final
。似乎代码正在访问一个可变静态,这是一个非常糟糕的主意。
对于您的特定代码,您可以写:
public IMethodFinder(String projectName, String methodName,
int numberOfParameters) {
this(
JavaCore.create(
ResourcesPlugin.getWorkspace().getRoot().getProject(projectName)
),
methodName,
numberOfParameters
);
}
更普遍的hack是在对构造函数的调用中调用静态方法:
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月:在消息Records: construction and validation中,Oracle建议删除此限制(但与C#不同,this
在构造函数链接之前肯定会被取消分配(DU))。
从历史上看,this()或super()必须是构造函数中的第一个。这种限制从未受到欢迎,并被认为是武断的。有许多微妙的原因,包括验证特殊参与,导致了这种限制。多年来,我们已经在虚拟机层面解决了这些问题,以至于考虑解除这一限制变得切实可行,不仅仅是记录,而是所有构造函数。
解决方案1:您的构造函数应该具有更好的定向流程,以避免使用常见的init
。通常一个构造函数将更基本并构造一个完整的有效对象,然后外部构造函数可以装饰它。
解决方案2:使用静态工厂方法通常是一种很好的做法,例如,可以在此处理所需的预处理。这看起来像这个模式的一个很好的用例。
解决方案3:代替常见的init
方法,只需使用静态方法为您执行隔离预处理。例如myField = processInputField(myField)
。常见的init
方法在最终字段中表现得非常糟糕,这是一个更糟糕的理由 - 实际上,是的,构造函数应该完成构建的全部工作。
关于你的第二个问题,请参阅this answer到你的第一个问题 - 是的,对于这些案例使用某种init()方法是相对被接受的
看看这个。它可能有助于理解java构造函数调用。
Constructor call must be the first statement in a constructor
以上是关于“构造函数调用必须是构造函数中的第一个语句”Java中的问题[重复]的主要内容,如果未能解决你的问题,请参考以下文章