奇怪的 JAVA 语法

Strange JAVA Syntax

以下代码用于 Spring - Hibernate Full Java Based Configuration 许多地方(如 here):

Properties hibernateProperties() {
        return new Properties() {
            {
                setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
                setProperty("hibernate.show_sql", "true");
                setProperty("hibernate.format_sql", "true");
                setProperty("use_sql_comments", "true");
                setProperty("hibernate.hbm2ddl.auto", "none");
            }
        };
    }

这是class中的一个方法。我认为 return 对象是一个匿名的 class 对象(如果我错了请告诉我)。包含 setProperty 语句的大括号是什么?那是一个数组吗?如果是这样,那里不应该有任何分号吗?

我没能找到任何解释此语法的地方。请给出一些 link 详细解释的地方。

这是 returns 类型 Properties 对象的方法。该方法创建一个 anonymous class which defines an instance initializer block,它在返回的对象中设置一些属性:

return new Properties() {
    // this is an instance initializer block which pre-sets some properties
    {
         setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
         setProperty("hibernate.show_sql", "true");
         setProperty("hibernate.format_sql", "true");
         setProperty("use_sql_comments", "true");
         setProperty("hibernate.hbm2ddl.auto", "none");
     }
};

它创建一个具有预定义属性的 Properties 对象。

类 可以包含 initialization blocks(静态和非静态)。在非静态块的情况下,它们的代码将在 class 的每个构造函数的开头移动(实际上几乎在开头,因为它将被放置在显式或隐式 super() 调用之后)。

所以class喜欢

class Foo{

    void method(){
        System.out.println("method()");
    }

    Foo(){
        System.out.println("constructor of Foo");
    }

    {
        System.out.println("initialization block");
        method();
    }

    public static void main(String[] args) {
        Foo f = new Foo();
    }

}

相同
class Foo {

    void method() {
        System.out.println("method()");
    }

    Foo() {
        super();
        //initialization block is moved here
        {
            System.out.println("initialization block");
            method();
        }
        System.out.println("constructor of Foo");
    }


    public static void main(String[] args) {
        Foo f = new Foo();
    }

}

因此,在这个初始化块中,您可以调用 Foo class 的任何方法,就像您可以在构造函数中调用它们一样。