换句话说,为什么需要实例初始化程序?在构造函数上编写实例初始化程序有什么区别或优势?
答案 0 :(得分:100)
这似乎解释得很好:
实例初始值设定项是实例变量的有用替代方法 初始化者:
初始化代码必须捕获异常,或
执行无法用实例变量初始化程序表示的奇特计算。 当然,您可以随时编写此类代码 构造函数。
但是在具有多个构造函数的类中,您必须在每个构造函数中重复代码。使用实例初始化程序,您 只需编写一次代码,无论如何都会执行 构造函数用于创建对象。实例初始化器是 在匿名内部类中也很有用,它们不能声明任何内容 完全是构造函数。
来自:JavaWorld Object initialization in Java。
答案 1 :(得分:20)
就对象生命周期而言,没有区别。两者都在构造时调用,逻辑上初始化块可以被视为构造的一部分。
从语义上讲,初始化程序是一个很好的工具,原因如下:
初始化程序可以通过将初始化逻辑保持在初始化变量旁边来提高代码可读性:
public class Universe {
public int theAnswer;
{
int SIX = 6;
int NINE = 7;
theAnswer = SIX * NINE;
}
// a bunch of other vars
}
VS
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
}
}
无论如何都会调用初始值设定项 使用哪个构造函数。
初始化程序可以匿名使用 内部类,构造函数 不能。
答案 2 :(得分:8)
当你有许多构造函数并希望为每个构造函数执行一些公共代码时,你可以使用实例初始化器。因为它是为所有构造函数调用的。
答案 3 :(得分:4)
我会避免使用实例初始化程序习惯用法 - 它对变量初始化程序的唯一真正优势是异常处理。
由于init方法(可以从构造函数调用)也可以进行异常处理并集中构造函数设置代码,但是它具有可以对构造函数参数值进行操作的优点,我会说实例初始化程序是冗余的,并且因此要避免。
答案 4 :(得分:4)
当我们使用匿名内部类时,可以看到实例初始化器相对于构造函数的真正优势。
匿名内部类不具备构造函数(因为他们是匿名的), 所以他们'非常适合实例初始化程序。
答案 5 :(得分:0)
初始化程序是在构造函数之间共享代码的方法,如果初始化程序与变量声明一起使用,它会使代码更具可读性。
Java编译器将初始化程序块复制到每个构造函数中。因此,该方法可用于在多个构造函数之间共享代码块。 Oracle documentation
答案 6 :(得分:0)
在创建对象时,如果要执行实例变量的初始化,则应使用Constructor,而不是初始化活动,如果要在创建对象时执行任何活动,则应去实例化
我们不能用实例块代替构造函数,因为构造函数可以接受参数,而实例块不能接受参数。
我们不能用构造函数替换实例块,因为一个类可以包含多个构造函数。如果要用构造函数替换实例块,那么在每个构造函数中都必须编写实例块代码,因为在运行时我们不能期望调用哪个构造函数,这会不必要地增加重复代码。
示例:
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