什么是非静态初始化块的替代方案?

Dim*_*ele 7 java constructor initialization block non-static

我的项目有一些喜欢非静态初始化块的开发人员.

有什么替代方案,这种替代方案的缺点是什么?我猜:在构造函数中初始化值

我们为什么要使用非初始化块?据我所知,"初始化块"用于在实例化类时设置值.那么构造函数是不够的?

public class BlockTest {
    String test = new String();

    //Non-static initialization block
    {
        test = "testString";
    }
}
Run Code Online (Sandbox Code Playgroud)

这个区块让我感到困惑,导致可读性降低.感谢您的答复!

Jas*_*n C 10

首先,将测试初始化​​为新的String()是没有意义的,因为初始化块会立即将其分配给其他东西.无论如何...

一种选择是在声明中初始化:

public class BlockTest {
    String test = "testString";
}
Run Code Online (Sandbox Code Playgroud)

另一个是在构造函数中:

public class BlockTest {
    String test;
    public BlockTest () {
        test = "testString";
    }
}
Run Code Online (Sandbox Code Playgroud)

这是两个主要的共同选择.

初始化块有两个主要用途.第一个是在初始化期间必须执行某些逻辑的匿名类:

new BaseClass () {
    List<String> strings = new ArrayList<String>();
    {
        strings.add("first");
        strings.add("second");
    }
}
Run Code Online (Sandbox Code Playgroud)

第二个是在每个构造函数之前必须进行的常见初始化:

public class MediocreExample {
    List<String> strings = new ArrayList<String>();
    {
        strings.add("first");
        strings.add("second");
    }
    public MediocreExample () {
        ...
    }
    public MediocreExample (int parameter) {
        ...
    }
}        
Run Code Online (Sandbox Code Playgroud)

但是,在这两种情况下都有不使用初始化块的替代方案:

new BaseClass () {
    List<String> strings = createInitialList();
    private List<String> createInitialList () {
        List<String> a = new ArrayList<String>();
        a.add("first");
        a.add("second");
        return a;
    }
}
Run Code Online (Sandbox Code Playgroud)

和:

public class MediocreExample {
    List<String> strings;
    private void initialize () {
        strings = new List<String>();
        strings.add("first");
        strings.add("second");
    }
    public MediocreExample () {
        initialize();
        ...
    }
    public MediocreExample (int parameter) {
        initialize();
        ...
    }
}        
Run Code Online (Sandbox Code Playgroud)

有很多方法可以做这些事情,使用最合适的方式,并提供最清晰,最容易维护的代码.


Evg*_*eev 7

编译器将非静态init块插入到每个构造函数中.初始化实例字段所需的代码也会插入到每个构造函数中.这个

class Test1 {
    int x = 1;
    {
        x = 2;
    }
    Test1() {
        x = 3;
    }
}
Run Code Online (Sandbox Code Playgroud)

编译成与此相同的字节码

class Test1 {
    int x;
    Test1() {
        x = 1;
        x = 2;
        x = 3;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这可能是真的,但问题的本质是语法和可观察的行为,而不是编译后的等效字节代码。+1清楚地说明了初始化的顺序(即使这不一定是您的目标)。 (2认同)