首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Java中的匿名代码块

Java中的匿名代码块
EN

Stack Overflow用户
提问于 2009-10-13 21:34:12
回答 7查看 44.7K关注 0票数 70

在Java中匿名代码块有什么实际用途吗?

代码语言:javascript
复制
public static void main(String[] args) {
    // in
    {
        // out
    }
}

请注意,这不是关于命名块,即

代码语言:javascript
复制
name: { 
     if ( /* something */ ) 
         break name;
}

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2009-10-13 21:36:31

它们限制变量的作用域。

代码语言:javascript
复制
public void foo()
{
    {
        int i = 10;
    }
    System.out.println(i); // Won't compile.
}

但在实践中,如果您发现自己在使用这样的代码块,这可能是您想要将该块重构为一个方法的信号。

票数 136
EN

Stack Overflow用户

发布于 2013-06-17 06:37:35

通常最好的方法是使用make the scope of local variables as small as possible。匿名代码块可以帮助实现这一点。

我发现这对switch语句特别有用。考虑下面的示例,不使用匿名代码块:

代码语言:javascript
复制
public String manipulate(Mode mode) {
    switch(mode) {
    case FOO: 
        String result = foo();
        tweak(result);
        return result;
    case BAR: 
        String result = bar();  // Compiler error
        twiddle(result);
        return result;
    case BAZ: 
        String rsult = bar();   // Whoops, typo!
        twang(result);  // No compiler error
        return result;
    }
}

和匿名代码块:

代码语言:javascript
复制
public String manipulate(Mode mode) {
    switch(mode) {
        case FOO: {
            String result = foo();
            tweak(result);
            return result;
        }
        case BAR: {
            String result = bar();  // No compiler error
            twiddle(result);
            return result;
        }
        case BAZ: {
            String rsult = bar();   // Whoops, typo!
            twang(result);  // Compiler error
            return result;
        }
    }
}

我认为第二个版本更干净,更容易阅读。而且,它将在switch中声明的变量的范围缩小到它们声明时的情况,根据我的经验,这是99%的情况下您想要的。

但是请注意,这不会改变失败的行为-您仍然需要记住包括一个breakreturn来防止它!

票数 23
EN

Stack Overflow用户

发布于 2009-10-13 23:10:29

我认为你和/或其他答案混淆了两个不同的语法结构;即实例初始化器和块。(顺便说一句,“命名块”实际上是一个带标签的语句,其中的语句恰好是一个块。)

实例初始化器在类成员的语法级别上使用;

代码语言:javascript
复制
public class Test {
    final int foo;

    {
         // Some complicated initialization sequence; e.g.
         int tmp;
         if (...) {
             ...
             tmp = ...
         } else {
             ...
             tmp = ...
         }
         foo = tmp;
    }
}

根据@dfa的示例,Initializer构造最常用于匿名类。另一个用例是对'final‘属性进行复杂的初始化;例如,参见上面的示例。(但是,更常见的做法是使用常规构造函数。上面的模式更常用于静态初始化器。)

另一个结构是一个普通的块,出现在一个代码块中,比如method;

代码语言:javascript
复制
public void test() {
    int i = 1;
    {
       int j = 2;
       ...
    }
    {
       int j = 3;
       ...
    }
}

块最常用作控制语句的一部分,用于对一系列语句进行分组。但是当你在上面使用它们时,它们(只是)允许你限制声明的可见性;例如上面的j

这通常意味着你需要重构你的代码,但它并不总是清晰的。例如,您有时会在用Java编写的解释器中看到这种事情。切换臂中的语句可以分解到单独的方法中,但这可能会对解释器的“内部循环”造成显著的性能影响;

代码语言:javascript
复制
    switch (op) {
    case OP1: {
             int tmp = ...;
             // do something
             break;
         }
    case OP2: {
             int tmp = ...;
             // do something else
             break;
         }
    ...
    };
票数 17
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1563030

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档