可能的重复:
为什么this()和super()必须是构造函数中的第一条语句?
我想要一个在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)
{
...
}
}
解决方案1:您的构造函数应该有一个指导更好的流,以避免使用通用的init
。通常,一个构造函数会更基本,构造一个完整的有效对象,然后外部构造函数可以修饰它。
解决方案2:使用静态工厂方法通常是一个很好的实践,例如,它可以处理您需要的预处理。这看起来是这个模式的一个很好的用例。
解决方案3:不使用普通的init
方法,而是使用静态方法为您进行独立的预处理。例如myField=processInputField(myField)
。常见的init
方法对final字段的处理很差,这是它们是糟糕实践的一个更有力的原因--本质上,是的,构造函数应该完成构造的全部工作。
没有内在的原因为什么不能将Java扩展为允许在构造函数之前不访问this
的语句。但是,这会增加语言的复杂性,并在使用时使代码变得模糊不清(特别是当您认为调用可能是隐式的时候)。
通常,您希望构造函数尽可能简单。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月:在message Records:construction and validation中,Oracle建议删除此限制(但与C#不同,this
将在构造函数链接之前明确取消赋值(DU))。
历史上,this()或super()必须是构造函数中的第一个。这种限制从来不受欢迎,而且被认为是武断的。有许多微妙的原因,包括对invokespecial的验证,促成了这种限制。多年来,我们已经在VM级别上解决了这些问题,现在考虑取消这个限制变得切实可行了,不仅仅是对记录,而且对所有构造函数都是如此。
如果将移到构造函数的最后一行,我不明白为什么下面的代码会显示错误。 我已经检查了很多关于StackOverflow的答案,但我仍然不能理解这其中的原因。请帮我用一些简单的例子和解释弄清楚这个错误。
问题内容: 以下代码向我返回错误信息: 我不明白。我的代码中的构造函数是第一条语句。我究竟做错了什么? 问题答案: 构造函数名称必须与类名称相同,因此请将类名称更改为或将构造函数名称更改为。 示例 (请注意,在Java中通常第一个字母是大写字母) :
我有一个班在Java延伸了另一个班 我需要构造函数来运行超级ctor 这是我的基本代码: 我想从子类中调用它 我怎么做,因为我得到错误“构造函数调用必须是构造函数中的第一个语句”,但我需要构建ctor 谢谢
这个Super()的替代品是什么;我代码中的语句...因为它向我显示了一个名为:构造函数调用必须是构造函数中的第一个语句的错误。
问题内容: 我正在编写一个LoginRequest类的构造函数,该类扩展了一个名为JsobObjectRequest的类(来自Android的Volley框架,但这与问题完全无关) 使用此代码: 我收到错误:对super()的调用必须是构造函数主体中的第一条语句 相反,此代码可以正常编译: 但这实际上不是一回事吗?在这两种情况下,根据传递给子类构造函数的参数值,在调用超级构造函数之前都要进行一些简
我正在编写一个LoginRequest类的构造函数,该类扩展了一个名为JsobObjectRequest的类(来自Android的凌空框架,但这与问题完全无关) 使用此代码: 我得到了一个错误:对super()的调用必须是构造函数体中的第一条语句 相反,这段代码编译得很好: 但事实上不是完全一样吗?在这两种情况下,在调用超级构造函数之前,都会根据传递给子类构造函数的参数值进行一些简单的计算。既然编