Java 在调用super()之前声明变量,但super必须是第一条语句

Java 在调用super()之前声明变量,但super必须是第一条语句,java,constructor,Java,Constructor,我在一个抽象类中有一个构造函数,在它的构造函数中有许多参数 public class Test extends YourFancySuperclassWithToManyParametersInConstructor { int a = 0; int b = 0; ... public Test() { super(a,b,...); } } 我试图扩展这个类,我想在扩展构造函数中对super()的调用中设置一些默认值 问题在于,通

我在一个抽象类中有一个构造函数,在它的构造函数中有许多参数

public class Test extends YourFancySuperclassWithToManyParametersInConstructor {
    int a = 0;
    int b = 0; 
    ...
    public Test() {
          super(a,b,...);
    }
}
我试图扩展这个类,我想在扩展构造函数中对super()的调用中设置一些默认值

问题在于,通过查看代码,它看起来很混乱:

super(0,1,2,3,4,5,6,7,8,9);
(请记住,这对于堆栈溢出是简化的)

我想做的是让构造函数如下所示:

    public Test(){
    int a = 0;
    int b = 1;
    int c = 2;
    int d = 3;
    int e = 4;
    int f = 5;
    int g = 6;
    int h = 7;
    int i = 8;
    int j = 9;
    super(a,b,c,d,e,f,g,h,i,j);
}

纯粹为了视觉和便于阅读的目的。有什么办法可以做到这一点吗?

没有。对
super
的调用必须是构造函数的第一行。 不过,您可以将这些默认值定义为类的静态最终成员

static final int a = 0;
static final int b = 1;
static final int c = 2;
static final int d = 3;
static final int e = 4;
static final int f = 5;
static final int g = 6;
static final int h = 7;
static final int i = 8;
static final int j = 9;

public Test()
{
    super(a,b,c,d,e,f,g,h,i,j);
}

不,没有。对
super
的调用必须是构造函数的第一行。 不过,您可以将这些默认值定义为类的静态最终成员

static final int a = 0;
static final int b = 1;
static final int c = 2;
static final int d = 3;
static final int e = 4;
static final int f = 5;
static final int g = 6;
static final int h = 7;
static final int i = 8;
static final int j = 9;

public Test()
{
    super(a,b,c,d,e,f,g,h,i,j);
}

您可以将变量移到构造函数之外

public class Test extends YourFancySuperclassWithToManyParametersInConstructor {
    int a = 0;
    int b = 0; 
    ...
    public Test() {
          super(a,b,...);
    }
}

您可以将变量移到构造函数之外

public class Test extends YourFancySuperclassWithToManyParametersInConstructor {
    int a = 0;
    int b = 0; 
    ...
    public Test() {
          super(a,b,...);
    }
}

不,你不能这样做,但是如果重要的部分是给参数有意义的名字,你可以考虑类似的事情:

class Foo extends Bar {
    private static final int DEFAULT_WIDTH = 10;
    private static final int DEFAULT_HEIGHT = 10;

    public Foo() {
        super(DEFAULT_WIDTH, DEFAULT_HEIGHT);
    }
}
就我个人而言,我发现这比在构造函数中使用局部变量更容易解释

另一种解释方法是评论:

public Foo() {
    super(
        10,  // width
        10); // height
}

<>这只是与你的“声明单独的变量”代码相同的行数。

不,你不能这样做,但是如果重要的部分是给参数有意义的名字,你可以考虑类似的事情:

class Foo extends Bar {
    private static final int DEFAULT_WIDTH = 10;
    private static final int DEFAULT_HEIGHT = 10;

    public Foo() {
        super(DEFAULT_WIDTH, DEFAULT_HEIGHT);
    }
}
就我个人而言,我发现这比在构造函数中使用局部变量更容易解释

另一种解释方法是评论:

public Foo() {
    super(
        10,  // width
        10); // height
}

无论如何,这只会与“声明独立变量”代码的行数相同。

声明常量的Java惯例是使用“最终静态”变量,因此我认为您可以这样做:

public class Y extends X {
    private static final int p1 = 1;
    private static final int p2 = 1;
    private static final int p3 = 1;

    public Y() {
        super(p1, p2, p3);
    }
}

声明常量的Java约定是使用“final static”变量,因此我想您可以这样做:

public class Y extends X {
    private static final int p1 = 1;
    private static final int p2 = 1;
    private static final int p3 = 1;

    public Y() {
        super(p1, p2, p3);
    }
}

我认为有更好的方法来设置super类的值,但是如果在调用super之前需要计算变量,我知道的唯一方法就是在静态方法中这样做,并将该方法的调用写入super调用的参数列表中。
例如:

 class MySuper {
    int i1;
    int i2;
    int i3;
    public MySuper(int i, int ii, int iii){
        i1 = i;
        i2 = ii;
        i3 = iii;
    }
}

class MyClass extends MySuper {
    public MyClass() {
        super(calc1(), calc2(), calc3());
    }

    private static int calc1() {
        return 1;
    }
    private static int calc2() {
        return 2;
    }
    private static int calc3() {
        return 3;
    }
}

但是如果你只需要常量,那么其他答案会更好。

我认为有更好的方法来设置超类的值,但是如果你需要在调用super之前计算变量,我知道的唯一方法就是在静态方法中这样做,并将该方法的调用写入super调用的参数列表中。
例如:

 class MySuper {
    int i1;
    int i2;
    int i3;
    public MySuper(int i, int ii, int iii){
        i1 = i;
        i2 = ii;
        i3 = iii;
    }
}

class MyClass extends MySuper {
    public MyClass() {
        super(calc1(), calc2(), calc3());
    }

    private static int calc1() {
        return 1;
    }
    private static int calc2() {
        return 2;
    }
    private static int calc3() {
        return 3;
    }
}

但是如果您只需要常量,那么其他答案会更好。

您不能将所有这些变量设置为类成员吗?或者它们必须是特定于方法的?
super(0,1,2,3,4,5,6,7,8,9)一点也不凌乱。但看起来家长的构造函数可以改进。有时这么多的参数表明你们很多人违反了单一责任原则。如果不是这样的话,也许使用工厂或构建器类进行重构是为了解决这个问题。不幸的是,这不是我要更改的类,所以我不能更改父类的构造函数。您可以不将所有这些变量设置为类成员吗?或者它们必须是特定于方法的?
super(0,1,2,3,4,5,6,7,8,9)一点也不凌乱。但看起来家长的构造函数可以改进。有时这么多的参数表明你们很多人违反了单一责任原则。如果不是这样的话,也许使用factory或builder类进行重构是为了解决这个问题。不幸的是,这不是我要更改的类,因此我无法更改父类的构造函数,尽管它们是字段,但没有迹象表明OP需要这些额外字段。但是,它们是字段,也没有迹象表明OP需要这些额外字段。我认为用注释分离变量是唯一真正的方法。知道变量和数据类型是很有用的,所以我把它放在每个变量旁边的注释中:)。我认为用注释分离变量是唯一真正的方法。了解变量和数据类型是很有用的,所以我在每个变量和数据类型旁边的注释中都添加了:)。