8

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

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

为什么要使用非初始化块?据我了解,“初始化块”用于在实例化类时设置值。那么构造函数还不够吗?

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

    //Non-static initialization block
    {
        test = "testString";
    }
}

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

4

3 回答 3

10

首先,在那里将 test 初始化为 new String() 是没有意义的,因为初始化块会立即将其分配给其他东西。无论如何...

一种替代方法是在声明中初始化:

public class BlockTest {
    String test = "testString";
}

另一个在构造函数中:

public class BlockTest {
    String test;
    public BlockTest () {
        test = "testString";
    }
}

这是两个主要的常见选项。

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

new BaseClass () {
    List<String> strings = new ArrayList<String>();
    {
        strings.add("first");
        strings.add("second");
    }
}

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

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

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

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

和:

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();
        ...
    }
}        

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

于 2013-08-07T07:04:33.047 回答
7

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

class Test1 {
    int x = 1;
    {
        x = 2;
    }
    Test1() {
        x = 3;
    }
}

编译成与此相同的字节码

class Test1 {
    int x;
    Test1() {
        x = 1;
        x = 2;
        x = 3;
    }
}
于 2013-08-07T07:10:08.483 回答
2

初始化块别无选择,实际上它是构造函数的替代方案。

public TestClass {
        TestClass() {

        }
    }

这在匿名类的情况下很有用,因为你不能有一个构造函数,原因很简单,你没有类的名称,那么你就不能有构造函数,否则你会怎么命名它.

new MyClass(){
   //its an anonymous class, you can't use constructor here
      {
      }
  }

但是,您可以使用声明内联初始化变量,例如

public TestClass {
    String test = "value";
}

但这不是一种选择,因为您不能以这种方式执行任何操作(例如算术或字符串操作),但您可以在初始化程序块中执行

public TestClass {
        String test = "value";
        test = test + " not found"//compiler error
        {
         test = test + " not found" // valid
        }
    }
于 2013-08-07T07:04:22.733 回答