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

时间:2013-08-07 07:01:36

标签: java constructor initialization block non-static

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

这个 替代 是什么?此备选方案的缺点是什么?我猜:在 构造函数中初始化值?

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

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

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

这个区块让我感到困惑,导致可读性降低。谢谢你的回复!

3 个答案:

答案 0 :(得分:10)

首先,将测试初始化​​为新的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();
        ...
    }
}        

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

答案 1 :(得分:6)

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

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

编译成与此

相同的字节码
class Test1 {
    int x;
    Test1() {
        x = 1;
        x = 2;
        x = 3;
    }
}

答案 2 :(得分:2)

initiaization block没有其他选择,实际上它是构造函数的替代。

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
        }
    }