如何在Java中初始化非静态类变量?

如何在Java中初始化非静态类变量?,java,class,oop,Java,Class,Oop,我们可以做到: class A { // some code } class B { A obj = new A(); // ??? } 查询: 我的理解是,obj(类A)的实例不是静态的,因此在B的类内存中不可用 在这种情况下,是否会对B的每个实例进行初始化 如果obj实际上停留在B的类内存中(即静态),那么实例obj的初始化将在何时发生 不管怎样,这是一种好的做法吗 那么,如果我们能做到这一点,为什么还要有构造函数呢 请随意更正。像这样初始化的字段是常见的做法 您可

我们可以做到:

class A {
     // some code
}

class B {
    A obj = new A(); // ???
}
查询:

  • 我的理解是,
    obj
    (类
    A
    )的实例不是静态的,因此在
    B的类内存中不可用
  • 在这种情况下,是否会对
    B
    的每个实例进行初始化
  • 如果
    obj
    实际上停留在
    B
    的类内存中(即静态),那么实例
    obj
    的初始化将在何时发生
  • 不管怎样,这是一种好的做法吗
  • 那么,如果我们能做到这一点,为什么还要有构造函数呢

请随意更正。

像这样初始化的字段是常见的做法

您可以将它们视为构造函数的一部分,类似于实例初始值设定项块

我们仍然有构造函数,因为您有时需要参数和复杂的逻辑


如果您有多个构造函数(字段将针对每个代码路径进行初始化),则该模式尤其方便。

像这样初始化的字段是常见的做法

您可以将它们视为构造函数的一部分,类似于实例初始值设定项块

我们仍然有构造函数,因为您有时需要参数和复杂的逻辑

如果您有多个构造函数(每个代码路径的字段都将被初始化),则该模式尤其方便

A不是静态的,因此在类内存中不可用

Right.class
A
将在实例化
B
时实例化

是否为B的每个对象预初始化

是。每当您创建
B
的对象时,也会创建
A
对象

无论哪种方式,这都是一种好的做法吗

实际上,这与通过构造函数实例化是一样的。所以无论是好的还是坏的做法都没有问题

那么,如果我们能做到这一点,为什么还要有构造函数呢

如果有多个构造函数,则不必在每个构造函数中实例化
A

A不是静态的,因此在类内存中不可用

Right.class
A
将在实例化
B
时实例化

是否为B的每个对象预初始化

是。每当您创建
B
的对象时,也会创建
A
对象

无论哪种方式,这都是一种好的做法吗

实际上,这与通过构造函数实例化是一样的。所以无论是好的还是坏的做法都没有问题

那么,如果我们能做到这一点,为什么还要有构造函数呢

如果有多个构造函数,则不必在每个构造函数中实例化
A

A不是静态的,因此在类内存中不可用

对。您必须有一个
B
的实例才能获得字段
A obj

是否为B的每个对象预初始化

对。将为每个创建的
B
创建一个单独的
新A

如果必须保留在obj内存中,那么何时进行初始化

不适用

无论哪种方式,这都是一种好的做法吗

对。它被称为,从其他对象组合对象是使用面向对象设计分解问题的两种主要方法之一。另一个是继承

那么,如果我们能做到这一点,为什么还要有构造函数呢

这只是语法糖。以下所有内容都是等效的

class B {
  A obj = new A();  // field initializer
}

class B {
  A obj;
  B() {
    A = new A();  // initialized in constructor
  }
}

class B {
  A obj;
  { obj = new A(); }  // instance initializer
}
只要在初始化期间没有任何内容读取obj,在字段、构造函数或显式初始化器中进行初始化就没有明显的区别

有时,在声明字段的位置赋值更方便

A不是静态的,因此在类内存中不可用

对。您必须有一个
B
的实例才能获得字段
A obj

是否为B的每个对象预初始化

对。将为每个创建的
B
创建一个单独的
新A

如果必须保留在obj内存中,那么何时进行初始化

不适用

无论哪种方式,这都是一种好的做法吗

对。它被称为,从其他对象组合对象是使用面向对象设计分解问题的两种主要方法之一。另一个是继承

那么,如果我们能做到这一点,为什么还要有构造函数呢

这只是语法糖。以下所有内容都是等效的

class B {
  A obj = new A();  // field initializer
}

class B {
  A obj;
  B() {
    A = new A();  // initialized in constructor
  }
}

class B {
  A obj;
  { obj = new A(); }  // instance initializer
}
只要在初始化期间没有任何内容读取obj,在字段、构造函数或显式初始化器中进行初始化就没有明显的区别


有时候,在声明字段的地方赋值更方便。

也许我曾经使用过java,但我看不到您的代码示例有什么不寻常的地方。这种情况很普遍。你能解释一下你发现的奇怪之处吗?Java中“类变量”的同义词是“静态变量”。因此,Java中的短语“非静态类变量”是一个矛盾修饰法。@Bohemian我已经说明了我在查询中发现的奇怪之处。@scottb我正在寻找一个术语来明确地说
非静态的
。也许我习惯于Java,但我没有看到您的代码示例有任何异常。这种情况很普遍。你能解释一下你发现的奇怪之处吗?Java中“类变量”的同义词是“静态变量”。因此,Java中的短语“非静态类变量”是一个矛盾修饰法。@Bohemian我已经说明了我在查询中发现的奇怪之处。@scottb我正在寻找一个术语来明确地说
非静态
。“编译器知道
B
需要
a
,所以
a
将在
B
实例化时实例化。”这有点误导<当实例化
B
时,将实例化code>A