java - 实例初始化器的用例

标签 java oop

我知道实例初始值设定项将在我的构造函数之前被调用,它们就像静态构造函数,只是每次我创建类的实例时都会调用它们。例如

public class App {    
    public static void main( String[] args ){
        new App();
        new App();
    }

    static{
        System.out.println( "static initializer" );
    }

    public App(){
        System.out.println( "constructor" );
    }

    {
        System.out.println( "instance initializer" );
    }
}

输出:

static initializer
instance initializer
constructor
instance initializer
constructor

但我为什么要使用它们?我可以在我的构造函数中编写逻辑,如果我想在一些已经存在的构造函数之前执行逻辑,我可以将它添加到构造函数的开头。

我也看不出继承类有什么优势,因为即使我覆盖了构造函数,我仍然可以只实现自己的逻辑并在之后调用父构造函数。

什么是 Java 或任何语言中实例初始化器的正确用例?或者总是有可能通过构造函数获得相同的功能?

最佳答案

来自JLS 8.6 - Instance Initializers :

An instance initializer declared in a class is executed when an instance of the class is created.

来自JLS 8.8 - Constructor Declarations :

A constructor is used in the creation of an object that is an instance of a class.

从而证实了您的观点,即在实例初始化器中完成的所有事情也可以在您的构造函数中完成。

这就留下了邻近性。比较:

Map<String, String> lookup = new HashMap<>();

{
    lookup.put("Hello", "Hello");
}

与:

Map<String, String> lookup = new HashMap<>();

// Maybe some considerable number of lines of code.
public Test() {
    lookup.put("Hello", "Hello");
}

这两者之间显然没有功能差异,但将两者放在一起更有意义。

当然也有边缘情况:

public Test() throws Exception {
   // ...
}

您不能在实例初始化器中执行此操作。

关于java - 实例初始化器的用例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35436122/

相关文章:

java - Maven 在 Linux 上找不到编译器

java - 如何反向选择sql中的列?

java - 如何同时添加响应id和加入对象

java - CachingAuthenticator 在 Dropwizard 中的使用

oop - 什么是 'exceptional' ?

c# - 你如何在 C# 中隐藏封装?

C++ : Association, 聚合和组合

java - 如何在java多线程环境中复制ArrayList<T>?

perl - 在 Perl 中,在属性中保留对 Catalyst 的 $c 的引用会导致内存泄漏吗?

javascript - 就良好实践而言,带有闭包的 javascript 原型(prototype)是一件好事吗