Java 如何初始化实例成员?

Java 如何初始化实例成员?,java,Java,定义Java类时: class A { private String str = "init method 1"; public A() { str = "init method 2"; } } 我可以在定义它时初始化str,也可以在构造函数中初始化它。我的问题是这两种方法的区别是什么?首选哪种方法?区别在于分配发生的时间。 字段是在构造函数运行之前分配的常量值,因此如果将此行添加到构造函数中: System.out.println(str); 在构造函数中

定义Java类时:

class A {
   private String str = "init method 1";

   public A() {
       str = "init method 2";
   }
}

我可以在定义它时初始化
str
,也可以在构造函数中初始化它。我的问题是这两种方法的区别是什么?首选哪种方法?

区别在于分配发生的时间。 字段是在构造函数运行之前分配的常量值,因此如果将此行添加到构造函数中:

System.out.println(str);
在构造函数中分配新值之前,您将看到旧值已经存在

除了这一点,没有太大的区别,使用哪一个主要是个人偏好


就我个人而言,任何我可以作为字段声明的一部分直接赋值的项-我就是这么做的。

初始化块值在构造函数赋值之前赋值

因此,将首先分配值
init member 1
,然后分配
init member 2

考虑一下这个例子

这个输出

In first static init block
In second static int block
In first instance init block, name = null
In second instance init block, name = null
In no argument constructor, name = prasad
In first instance init block, name = null
In second instance init block, name = null
In no argument constructor, name = prasad
In first instance init block, name = null
In second instance init block, name = null
In 1 argument constructor, name = null
程序流程如下

  • 当程序开始执行时,类
    InitBlocksDemo
    被加载到JVM中
  • 静态初始化块在类按照它们在程序中出现的顺序加载时运行
  • 现在,当静态块的执行完成时,会遇到
    main
    方法
  • 语句
    newinitblocksdemo()导致调用无参数构造函数
  • 由于存在对
    super
    no-argument构造函数的默认调用,因此控制转到super类,即
    Object
    class
  • 完成后,控件返回到我们的类并开始为实例变量提供默认值。在这种情况下,变量名将被赋值为
    null
  • 现在,实例块将按照它们在程序中出现的顺序执行。我们还没有为name变量重新赋值,所以它将打印
    null
  • 执行实例块后,控制权转到构造函数。此处name=“prasad”;将重新分配一个新值,因此“prasad”将打印在无参数构造函数中
  • 9.语句
    newinitblocksdemo(7)导致调用单参数构造函数。剩下的过程是一样的。唯一的区别是名称没有重新分配新值,因此它将打印
    null

它们之间没有区别,编译器将初始化块复制到构造函数

如果需要,请为该类反编译生成的类文件

class A {
    private String str1 = "init method 1";

    private String str2;

    public A() {
        str2 = "init method 2";
    }

    public A(String str2) {
        str2 = str2;
    }
}
你可以找到

class A
{

    private String str1;
    private String str2;

    public A()
    {
        str1 = "init method 1";
        str2 = "init method 2";
    }

    public A(String str2)
    {
        str1 = "init method 1";
        str2 = str2;
    }
}

根据我个人的经验,这一切都与对象初始化的成本或细节有关。其次,你也可以把它看作懒惰的创造和主动的创造。如果只涉及构造函数,我通常在实例变量级别创建对象。如果有进一步的调用来初始化所讨论的成员,那么肯定会将调用移动到构造函数或需要初始化它的方法


这就是为什么要使用factory方法模式,将实际的对象创建委托给另一个类。

您所说的是实例成员(类成员将是
静态的
)。请注意,您的问题没有单一的正确答案,因此答案将基于意见。请检查此问题:
class A
{

    private String str1;
    private String str2;

    public A()
    {
        str1 = "init method 1";
        str2 = "init method 2";
    }

    public A(String str2)
    {
        str1 = "init method 1";
        str2 = str2;
    }
}