我问的是关于c#,但我认为它在大多数其他语言中都是一样的.
有没有人对表达式和语句有一个很好的定义,有什么区别?
我正在处理一个扩展的类JFrame.
它不是我的代码,它super在开始构建GUI之前调用它.我想知道为什么这样做,因为我总是只是访问超类的方法而不必调用super();
在Java的构造函数中,如果要调用另一个构造函数(或超级构造函数),它必须是构造函数中的第一行.我假设这是因为在其他构造函数运行之前不应该允许修改任何实例变量.但是为什么你不能在构造函数委托之前有语句,以便计算其他函数的复杂值?我想不出任何好的理由,而且我遇到了一些真实的案例,我写了一些丑陋的代码来解决这个限制.
所以我只是想知道:
举一个我正在谈论的例子,考虑一下我在StackOverflow中给出的一些代码.在那段代码中,我有一个BigFraction类,它有一个BigInteger分子和一个BigInteger分母."规范"构造函数是BigFraction(BigInteger numerator, BigInteger denominator)表单.对于所有其他构造函数,我只是将输入参数转换为BigIntegers,并调用"规范"构造函数,因为我不想复制所有工作.
在某些情况下,这很容易; 例如,带两个longs 的构造函数是微不足道的:
public BigFraction(long numerator, long denominator)
{
this(BigInteger.valueOf(numerator), BigInteger.valueOf(denominator));
}
Run Code Online (Sandbox Code Playgroud)
但在其他情况下,这更难.考虑采用BigDecimal的构造函数:
public BigFraction(BigDecimal d)
{
this(d.scale() < 0 ? d.unscaledValue().multiply(BigInteger.TEN.pow(-d.scale())) : d.unscaledValue(),
d.scale() < 0 ? BigInteger.ONE : BigInteger.TEN.pow(d.scale()));
}
Run Code Online (Sandbox Code Playgroud)
我觉得这很难看,但它有助于我避免重复代码.以下是我想要做的,但它在Java中是非法的:
public BigFraction(BigDecimal d)
{
BigInteger numerator = null;
BigInteger denominator = null;
if(d.scale() < 0)
{
numerator = d.unscaledValue().multiply(BigInteger.TEN.pow(-d.scale()));
denominator = BigInteger.ONE;
}
else
{
numerator = d.unscaledValue();
denominator = BigInteger.TEN.pow(d.scale());
}
this(numerator, …Run Code Online (Sandbox Code Playgroud) 相当直截了当的问题.在C++中,父构造函数将在子构造函数之前被隐式调用,那么PHP有什么逻辑不以这种方式做事?
编辑:我得到了Lukman的一个很好的答案,但我希望有更多的原因可以解决这个问题.也许问题应该是为什么C++不允许自定义调用父构造函数?我猜这是另一个问题.
我有以下2个班级
public class classA {
classA() {
System.out.println("A");
}
}
class classB extends classA {
classB() {
System.out.println("B");
}
}
Run Code Online (Sandbox Code Playgroud)
然后跑
classA c = new classB();
Run Code Online (Sandbox Code Playgroud)
要么
classB c = new classB();
Run Code Online (Sandbox Code Playgroud)
总是给
A
B
Run Code Online (Sandbox Code Playgroud)
为什么会这样?乍一看,在任何一种情况下,我都会假设只classB调用构造函数,因此唯一的输出就是
B
Run Code Online (Sandbox Code Playgroud)
但这显然是错误的.
我有以下课程:
class Pair
{
String car;
Integer cdr;
public Pair () {}
public Pair (String car) { this.car = car; }
public Pair (Integer cdr) { this.cdr = cdr; }
public Pair (String car, Integer cdr)
{
this(car);
this(cdr);
}
}
Run Code Online (Sandbox Code Playgroud)
该类包含两个可选值,我想提供所有可能的构造函数排列.第一个版本不初始化任何内容,第二个版本仅初始化第一个值,第三个版本仅初始化第二个值.
最后一个构造函数是第二个和第三个的组合.但是不可能把它写下来,因为代码失败了.
constructor.java:13: call to this must be first statement in constructor
this(cdr);
^
1 error
是否可以编写最后一个没有任何代码冗余的构造函数(也没有调用相同的setter方法)?
我们来看看Java中的以下代码片段.
package trickyjava;
class A
{
public A(String s)
{
System.out.println(s);
}
}
final class B extends A
{
public B()
{
super(method()); // Calling the following method first.
}
private static String method()
{
return "method invoked";
}
}
final public class Main
{
public static void main(String[] args)
{
B b = new B();
}
}
Run Code Online (Sandbox Code Playgroud)
按照惯例,Java中的super()构造函数必须是相关构造函数体中的第一个语句.在上面的代码中,我们在super()构造函数参数列表中调用静态方法本身是super(method()); .
这意味着在构造函数B()中对super的调用中,在调用super之前调用了一个方法!这应该被编译器禁止,但它很好用.这有点等同于以下陈述.
String s = method();
super(s);
Run Code Online (Sandbox Code Playgroud)
但是,它是非法的,导致编译时错误,指示"调用super必须是构造函数中的第一个语句".为什么?为什么它等价超级(method()); 是有效的,编译器不再抱怨?
我想在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) {
...
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我收到错误"构造函数调用必须是构造函数中的第一个语句"错误.

我制作了一个在两个构造函数之间共享的公共代码,但我不确定这是绕过该问题的唯一解决方案.
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, …Run Code Online (Sandbox Code Playgroud) 我不明白为什么Constructor call must be the first statement in a constructor如果我转移this(1);到构造函数中的最后一行,下面的代码显示错误.
package learn.basic.corejava;
public class A {
int x,y;
A()
{
// this(1);// ->> works fine if written here
System.out.println("1");
this(1); //Error: Constructor call must be the first statement in a constructor
}
A(int a)
{
System.out.println("2");
}
public static void main(String[] args) {
A obj1=new A(2);
}
}
Run Code Online (Sandbox Code Playgroud)
我在StackOverflow上检查了很多关于这个主题的答案,但我仍然无法理解这个原因.请帮我用一些简单的例子和解释来说明这个错误.
我正在编写一个LoginRequest类的构造函数,它扩展了一个名为JsobObjectRequest的类(来自Android中的Volley框架,但这与问题完全无关)
使用此代码:
public LoginRequest(String username, String password, Response.Listener<JSONObject> responseListener, Response.ErrorListener errorListener) {
Boolean hasCredentials=(username!=null && password!=null);
int method=hasCredentials? Method.POST:Request.Method.GET;
super(method, API_URL_LOGIN, null, responseListener, errorListener);
this.username=username;
this.password=password;
}
Run Code Online (Sandbox Code Playgroud)
我得到错误:调用super()必须是构造函数体中的第一个语句
相反,这段代码编译得很好:
public LoginRequest(String username, String password, Response.Listener<JSONObject> responseListener, Response.ErrorListener errorListener) {
super((username!=null && password!=null)? Method.POST:Request.Method.GET, API_URL_LOGIN, null, responseListener, errorListener);
this.username=username;
this.password=password;
}
Run Code Online (Sandbox Code Playgroud)
但这不是有效的完全相同的事情吗?在这两种情况下,在调用超级构造函数之前,根据传递给子类构造函数的参数值,进行一些简单的计算.为什么编译器不能编译第一个例子,因为它可以编译第二个例子?
call-super-constructor-must-first-statement语句规范是否比它需要的更简单,或者我错过了什么?
编辑:这被错误地标记为重复为什么this()和super()必须是构造函数中的第一个语句?.这个问题更通用,并询问为什么super()必须是第一个声明.这里的问题是为什么像我发布的那样的案例会破坏这些要求(并且在这个问题中得到了令人满意的回答)
java ×8
constructor ×3
inheritance ×2
superclass ×2
c# ×1
expression ×1
oop ×1
php ×1
static ×1
super ×1
syntax ×1
this ×1