【发布时间】:2010-11-24 06:10:39
【问题描述】:
换句话说,为什么需要实例初始化器?与构造函数相比,编写实例初始化程序有什么不同或优势?
【问题讨论】:
-
实例初始化器非常少见(除非您遇到热衷于双括号习语的人的代码)。
标签: java instantiation
换句话说,为什么需要实例初始化器?与构造函数相比,编写实例初始化程序有什么不同或优势?
【问题讨论】:
标签: java instantiation
当您有许多构造函数并希望为每个构造函数执行一些公共代码时,您可以使用实例初始化程序。因为它被所有构造函数调用。
【讨论】:
就对象生命周期而言,没有区别。两者都在构造时调用,逻辑上初始化块可以被认为是构造的一部分。
从语义上讲,初始化器是一个不错的工具,原因如下:
初始化器可以通过将初始化逻辑保留在正在初始化的变量旁边来提高代码的可读性:
public class Universe {
public int theAnswer;
{
int SIX = 6;
int NINE = 7;
theAnswer = SIX * NINE;
}
// a bunch of other vars
}
对
public class Universe {
public int theAnswer;
// a bunch of other vars
public Universe() {
int SIX = 6;
int NINE = 7;
theAnswer = SIX * NINE;
// other constructor logic
}
}
不管怎样,初始化器都会被调用 使用了哪个构造函数。
初始化器可以匿名使用 内部类,其中构造函数 不能。
【讨论】:
theAnswer 标记了您的实例初始化程序代码。那是对的吗?或者我错过了什么。
theAnswer 是一个声明的实例变量。它在匿名初始化程序块中初始化。注意变量声明后的分号。
这似乎解释得很好:
实例初始化器是实例变量的有用替代品 任何时候的初始化器:
初始化代码必须捕获异常,或者
执行无法用实例变量初始化器表达的奇特计算。 当然,你总是可以在 构造函数。
但是在一个有多个构造函数的类中,你必须在每个构造函数中重复代码。使用实例初始化器,您 可以只写一次代码,无论如何都会执行 构造函数用于创建对象。实例初始化器是 在匿名内部类中也很有用,它不能声明任何 构造函数。
发件人:JavaWorld Object initialization in Java。
【讨论】:
一般来说,我会避免使用实例初始化器惯用语——它相对于变量初始化器的唯一真正优势是异常处理。
而且由于 init 方法(可从构造函数调用)也可以进行异常处理,也可以集中构造函数设置代码,但具有可以对构造函数参数值进行操作的优点,我会说实例初始化程序是多余的,并且因此要避免。
【讨论】:
初始化程序是在构造函数之间共享代码的一种方式,如果初始化程序与变量声明一起使用,它会使代码更具可读性。
Java 编译器将初始化程序块复制到每个构造函数中。因此,这种方法可用于在多个构造函数之间共享代码块。 Oracle documentation
【讨论】:
实例初始化器优于构造器的真正优势体现在我们使用匿名内部类时。
匿名内部类不能有构造函数(因为它们是匿名的), 所以它们非常适合实例初始化器。
【讨论】:
在创建对象时,如果我们想初始化实例变量,那么我们应该去构造器,如果我们想在创建对象时执行任何活动,那么我们应该去实例块。
我们不能用实例块替换构造器,因为构造器可以带参数,但实例块不能带参数。
我们不能用构造函数替换实例块,因为一个类可以包含多个构造函数。如果我们想用构造函数替换实例块,那么在每个构造函数中我们都必须编写实例块代码,因为在运行时我们无法预料会调用哪个构造函数,这会不必要地增加重复代码。
示例:
class MyClass{
static int object_count = 0;
MyClass(){
object_count++;
}
MyClass(int i){
object_count++;
}
void getCount() {
System.out.println(object_count);
}
public static void main(String... args) {
MyClass one = new MyClass();
MyClass two = new MyClass(2);
two.getCount();
}
}
输出: 2
class MyClass{
static int object_count = 0;
{
object_count++;
}
MyClass(){
}
MyClass(int i){
}
void getCount() {
System.out.println(object_count);
}
public static void main(String... args) {
MyClass one = new MyClass();
MyClass two = new MyClass(2);
two.getCount();
}
}
输出: 2
【讨论】: