java 构造函数初始化_java - 我应该在构造函数或外部构造中初始化变量

java - 我应该在构造函数或外部构造中初始化变量

这个问题在这里已有答案:

我应该在声明或构造函数中实例化实例变量吗?                                     13个答案

当我根据我的C ++知识使用Java时,我喜欢使用以下方式初始化变量。

public class ME {

private int i;

public ME() {

this.i = 100;

}

}

过了一段时间,我改变了习惯

public class ME {

private int i = 100;

public ME() {

}

}

我遇到了其他的源代码,有些使用了第1个约定,有些则使用了第2个约定。

我可以知道你们都推荐哪种惯例,为什么?

Cheok Yan Cheng asked 2019-03-14T04:52:15Z

11个解决方案

179 votes

我发现第二种风格(声明+初始化一次性)优越。原因:

它一目了然地表明变量是如何初始化的。 通常,在阅读程序并遇到变量时,您将首先转到其声明(通常在IDE中自动执行)。 使用样式2,您可以立即看到默认值。 对于样式1,您还需要查看构造函数。

如果您有多个构造函数,则不必重复初始化(并且您不能忘记它们)。

当然,如果初始化值在不同的构造函数中不同(或者甚至在构造函数中计算),则必须在构造函数中执行此操作。

sleske answered 2019-03-14T04:52:50Z

22 votes

我倾向于使用第二个来避免复杂的构造函数(或无用的构造函数),我也不认为这是初始化(即使它是初始化),但更像是给出一个默认值。

例如,在第二个代码段中,您可以删除构造函数并获得更清晰的代码。

Colin Hebert answered 2019-03-14T04:53:22Z

16 votes

我有几乎总是在构造函数中初始化的习惯(习惯)有两个原因,一个在我看来它增加了readablitiy(更干净),两个在构造函数中比在一行中有更多的逻辑控制。 即使最初实例变量不需要逻辑,但如果需要,在构造函数中使用它可以为将来添加逻辑提供更大的灵活性。

至于上面提到的关于多个构造函数的问题,通过使用一个no-arg构造函数来初始化所有构造函数初始化所有构造函数,然后每个构造函数在第一行调用this(),这很容易解决。 这解决了你的reduncancy问题。

Joseph Cozad answered 2019-03-14T04:53:53Z

6 votes

我在第一种方法中看到的唯一问题是,如果您计划添加更多构造函数。 然后你将重复代码,可维护性将受到影响。

Josmas answered 2019-03-14T04:54:17Z

5 votes

如果你在顶层或构造函数中初始化它没有太大的区别。但在某些情况下,在构造函数中初始化是有道理的。

class String

{

char[] arr/*=char [20]*/; //Here initializing char[] over here will not make sense.

String()

{

this.arr=new char[0];

}

String(char[] arr)

{

this.arr=arr;

}

}

因此,根据具体情况,您必须在顶部初始化,有时在构造函数中初始化。

FYI其他选项用于初始化而不使用构造函数:

class Foo

{

int i;

static int k;

//instance initializer block

{

//run's every time a new object is created

i=20;

}

//static initializer block

static{

//run's only one time when the class is loaded

k=18;

}

}

Emil answered 2019-03-14T04:54:56Z

3 votes

我建议在构造函数中初始化变量。 这就是它们存在的原因:确保正确构造(初始化)对象。

无论哪种方式都可以工作,这是一个风格问题,但我更喜欢构造函数进行成员初始化。

Bernard answered 2019-03-14T04:55:27Z

3 votes

有一点,无论您如何初始化该字段,如果可能,使用final限定符将确保在多线程环境中字段值的可见性。

Steve Emmerson answered 2019-03-14T04:55:52Z

2 votes

我认为两者都是正确的编程方式,

但我认为你的第一个选项在面向对象的方式更正确,因为在构造函数中是在创建对象时,并且是在变量应该初始化时。

我认为这是“按书”的惯例,但它可供讨论。

维基百科

mklfarha answered 2019-03-14T04:56:32Z

2 votes

根据您的具体情况,这两个选项都可以正确。

一个非常简单的例子是:如果你有多个构造函数,所有构造函数都以相同的方式初始化变量(对于每个构造函数,int x = 2)。 在声明时初始化变量以避免冗余是有意义的。

在这种情况下考虑最终变量也是有意义的。 如果你知道最终变量在声明时将具有什么值,那么在构造函数之外初始化它是有意义的。 但是,如果您希望类的用户通过构造函数初始化最终变量,请将初始化延迟到构造函数。

kasgoku answered 2019-03-14T04:57:11Z

1 votes

它可能取决于您的初始化,例如,如果涉及检查的异常,您不能仅使用字段初始化。 例如,以下内容:

public class Foo {

FileInputStream fis = new FileInputStream("/tmp"); // throws FileNotFoundException

}

将导致编译时错误,除非您还包含声明已检查异常的构造函数,或扩展一个超类,例如:

public Foo() throws FileNotFoundException {}

Jonathan answered 2019-03-14T04:57:44Z

0 votes

我会说,这取决于默认值。 例如

public Bar

{

ArrayList foos;

}

我会在构造函数外面做一个foos,如果我总是假设foos不能为null。 如果Bar是一个有效的对象,如果foos为空,则不关心,我会把它放在构造函数中。

您可能不同意并且说将对象置于有效状态是构造函数的工作。 但是,如果显然所有构造函数应该完全相同(初始化foos),为什么要重复该代码?

Ishtar answered 2019-03-14T04:58:23Z

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值