换句话说,为什么需要实例初始化器?与构造函数相比,编写实例初始值设定项有什么区别或优势?
Answers:
这似乎很好地解释了这一点:
在以下情况下,实例初始化器是实例变量初始化器的有用替代方法:
初始化程序代码必须捕获异常,或者
执行实例变量初始化程序无法表达的计算。当然,您始终可以在构造函数中编写此类代码。
但是在具有多个构造函数的类中,您将不得不在每个构造函数中重复执行代码。使用实例初始化器,您只需编写一次代码,无论使用什么构造函数创建对象,都将执行该代码。实例初始化器在匿名内部类中也很有用,匿名内部类根本不能声明任何构造函数。
来自:JavaWorld Java中的对象初始化。
就对象生命周期而言,没有区别。两者都在构造时被调用,从逻辑上讲,初始化程序块可以视为构造的一部分。
从语义上讲,初始化器是一个不错的工具,其原因如下:
通过将初始化逻辑放在要初始化的变量旁边,初始化器可以提高代码的可读性:
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
是一个声明的实例变量。它是在匿名初始化程序块中初始化的。注意变量声明后的分号。
当您有许多构造函数并希望为每个构造函数执行一些通用代码时,可以使用实例初始化器,因为所有构造函数都将调用它。
我通常会避免使用实例初始化程序的习惯用法-它提供的超过变量初始化程序的唯一真正优势是异常处理。
而且,由于init方法(可从构造函数调用)也可以执行异常处理并集中化构造函数设置代码,但具有可以对构造函数参数值进行操作的优点,因此我想说实例初始化器是多余的,因此可以避免。
在创建对象时,如果要执行实例变量的初始化,则应使用构造函数,除了初始化活动以外,如果要在创建对象时执行任何活动,则应转到实例块。
我们不能用实例块替换构造函数,因为构造函数可以接受参数,而实例块不能接受参数。
我们不能用构造函数替换实例块,因为一个类可以包含多个构造函数。如果我们想用构造函数替换实例块,那么在每个构造函数中我们都必须编写实例块代码,因为在运行时我们不会期望调用哪个构造函数,这会不必要地增加重复代码。
范例:
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