【问题标题】:In Java, why have a code block with no keywords, just curly brackets在Java中,为什么有一个没有关键字的代码块,只有大括号
【发布时间】:2011-05-25 09:15:10
【问题描述】:

我正在重构一些继承的代码,但被设计决策难住了,无法找出合适的术语来谷歌搜索。我的前任会使用这样的块:

public class ChildClass extends ParentClass {
    {
        inheritedVar = "someVal";
    }

    public ChildClass(){ /* constructor exists */ }
    // rest of code
}

声明没有关键字的代码块有什么意义?我不相信它的行为不像静态块。它是在构造函数中设置的替代方法吗?如果正在使用工厂(在这种情况下不是),这会产生一些影响吗?我在this happening in C 上找到了一个相关线程,但推理(范围和变量声明)似乎与 Java 无关。

任何关于“为什么”的想法或想法将不胜感激。重新考虑这一点很容易,我现在只是好奇。

【问题讨论】:

    标签: java design-patterns


    【解决方案1】:

    这是一个初始化块。 (与静态初始化块相关)请参阅本页上的初始化实例成员:

    http://download.oracle.com/javase/tutorial/java/javaOO/initial.html

    它是构造函数的替代方案。当提供多个重载的构造函数作为共享代码的一种方式时,您可以使用它。

    然而,就我个人而言,我发现让构造函数调用命名初始化方法比依赖匿名代码块要清楚得多。虽然,编译器确实将初始化程序块复制到幕后的所有构造函数,但您可能会争辩说,性能提升类似于内联方法声明。

    【讨论】:

    • +1:我同意命名初始化方法。然而,鉴于只有一个构造函数,我的代码库中这个块的全部意义似乎毫无意义。
    • @Riggy,这当然是多余的。
    【解决方案2】:

    它被称为initializer block

    实例变量的初始化块看起来就像静态初始化块,但没有 static 关键字:

        {
            // whatever code is needed for initialization goes here
        }
    

    Java 编译器将初始化程序块复制到每个构造函数中。因此,这种方法可用于在多个构造函数之间共享代码块。

    【讨论】:

    • 你和迈克都留下了很好的答案,感谢你们提供的链接。我没有考虑过多个重载的构造函数,因为我发现的各种类每个只有一个构造函数。
    • 一个小问题 - afaik 编译器不会复制初始化程序块,它只是将构造函数的调用添加到特殊的 方法,这就是 { } 在 .class 文件中的样子. [静态初始化块变成 方法。]
    【解决方案3】:

    你的前任还在学习。

    这是您可能得到的最佳解释。也许在某个时间点需要像这样拆分代码。很难说。代码当然应该这样写:

    公共类 ChildClass 扩展 ParentClass { 公共子类(){ 继承Var = "someVal"; } // 其余代码 }

    至于初始化程序块,其目的已由此处的其他答案给出。我提出了我的答案,试图回答你要求的“为什么”。不幸的是,要获得真正的答案,您必须询问您的前任。

    【讨论】:

    • 我只发布了最少量的代码来表达我的观点,而不会给 SO 读者带来垃圾代码的负担。我只包含了构造函数,以便很明显代码中存在构造函数,并且无名块没有替换构造函数。谢谢!
    • 没问题。我删除了我的回答中询问它的部分。
    • 你是对的,它不是最好的代码。我建议前任正在学习。有很多开发者称其他开发者为白痴,而这只是让人们隐藏他们的错误,以免他们感到尴尬或更糟,被解雇。我更愿意看到“您的前任仍在学习如何编写好代码”。我的使命是为开发人员提供安全的环境,让他们学习正确的做事方式,并强烈认为 StackOverflow 应该是其中之一 - 你愿意提供帮助并改变你使用的语言吗?
    • 是的,我愿意在这里做。我不应该假设代码是由应该知道他们在做什么的任何人编写的。人们被雇用随时学习。当然,如果我每次写一些愚蠢的代码都能得到一毛钱……
    • 对于我们任何人来说,都有一些我们不知道的事情。我不倾向于说它会让我们都是白痴,但如果是这样,我肯定不会把它放在广告牌上。
    【解决方案4】:

    范围。块中声明的任何变量都超出了块之后的范围。将变量的范围保持在最低限度是很有用的。

    另外,如果你定义了一个匿名内部类,你可以使用这个语法来构造构造函数。

    【讨论】:

    • 不完全。如果它在方法体中,它将是范围。这是在类主体中,在方法之外。阅读其他答案。
    • -1 这是一个错误的答案。在给定的情况下,它是一个初始化块。
    猜你喜欢
    • 1970-01-01
    • 2013-08-12
    • 2021-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    • 1970-01-01
    相关资源
    最近更新 更多