Java中的方法内部是否使用自由浮动块?

发布于 2024-10-09 00:46:11 字数 271 浏览 3 评论 0原文

我不知道方法可以有这样的浮动块:

class X { 
    public static void main( String [] args ) {
        { //<--- start
            int i;
        } //<-- ends
    }
}

我知道方法外部有浮动块,但从未在内部尝试过它们。

这可能用于定义本地范围或其他东西。

Java 方法中的浮动块有什么用?

I didn't know methods could have floating blocks like this:

class X { 
    public static void main( String [] args ) {
        { //<--- start
            int i;
        } //<-- ends
    }
}

I was aware of floating blocks outside methods, but never tried them inside.

This could probably be used to define local scope or something.

Is there a use for floating blocks inside methods in Java?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

秋叶绚丽 2024-10-16 00:46:11

有什么用吗?

是的 - 限制局部变量的范围。

这是个好主意吗?

可能是有争议的(而且很可能会是)。

“支持”阵营会说缩小变量的范围总没有坏处。 “反对派”阵营会说,如果您在方法中使用它,并且您的方法足够长,足以保证将变量的范围缩小到特定部分,那么这可能表明您应该从不同的部分中创建单独的方法。

就我个人而言,我使用它们,例如:

public void doGet(
        final HttpServletRequest request,
        final HttpServletResponse response)
  throws IOException {
    final PersistenceManager pm = PMF.get().getPersistenceManager();

    final List<ToDoListGaejdo> toDoLists;
    {
        final Query query = pm.newQuery(ToDoListGaejdo.class);
        query.setOrdering("listName asc");
        toDoLists = (List<ToDoListGaejdo>) query.execute();
    }

    final List<ToDoItemGaejdo> entries;
    {
        final Query query = pm.newQuery(ToDoItemGaejdo.class);
        query.setOrdering("listName asc, priority asc");
        entries = (List<ToDoItemGaejdo>) query.execute();
    }

    final ServletOutputStream out = response.getOutputStream();

    out.println("<head>");
    out.println("  <title>Debug View</title>");
    ....

Is there a use?

Yes - to limit the scope of local variables.

Is it a good idea?

Probably debatable (and likely will be).

The "pro" camp will say it never hurts to narrow the scope of variable. The "con" camp will say that, if you use it in a method and your method is long enough to warrant narrowing the scope of variables to specific sections, then it is probably an indication that you should make separate methods out of the different sections.

Personally, I use them, e.g.:

public void doGet(
        final HttpServletRequest request,
        final HttpServletResponse response)
  throws IOException {
    final PersistenceManager pm = PMF.get().getPersistenceManager();

    final List<ToDoListGaejdo> toDoLists;
    {
        final Query query = pm.newQuery(ToDoListGaejdo.class);
        query.setOrdering("listName asc");
        toDoLists = (List<ToDoListGaejdo>) query.execute();
    }

    final List<ToDoItemGaejdo> entries;
    {
        final Query query = pm.newQuery(ToDoItemGaejdo.class);
        query.setOrdering("listName asc, priority asc");
        entries = (List<ToDoItemGaejdo>) query.execute();
    }

    final ServletOutputStream out = response.getOutputStream();

    out.println("<head>");
    out.println("  <title>Debug View</title>");
    ....
耶耶耶 2024-10-16 00:46:11

块有用的另一种情况是在 switch 语句中;例如,以下内容无效

    switch (i) {
      case 1:
        float j = ...;
        break;
      case 2:
        float j = ...;  // compilation error
        break;
      ...
    }

,但添加块就可以了:

    switch (i) {
      case 1:
        {
          float j = ...;
          break;
        }
      case 2:
        {
          float j = ...;  // just fine
          break;
        }
      ...
    }

当您使用(大)switch 语句实现状态机和解释器之类的东西时,就会出现这种用例。您可能会争辩说局部变量都应该具有不同的名称,但是:

  • 在像这样的粗糙代码中对相同的概念使用相同的名称(尽管在不同的范围内)有利于大规模可读性,并且
  • 使用块使其更容易让编译器认识到其中声明的变量可以共享堆栈帧槽。如果封闭方法也是递归的,那么这可能很重要。

(好吧,这要么是微观优化,要么是微观优化的结果。但假设我们已经确定这是合理的。)

One further case where blocks are useful is in switch statements; e.g. the following is invalid

    switch (i) {
      case 1:
        float j = ...;
        break;
      case 2:
        float j = ...;  // compilation error
        break;
      ...
    }

but it is OK with added blocks:

    switch (i) {
      case 1:
        {
          float j = ...;
          break;
        }
      case 2:
        {
          float j = ...;  // just fine
          break;
        }
      ...
    }

This kind of use-case arises when you implement things like state machines and interpreters using (big) switch statements. You could argue that the local variables should all have different names, but:

  • using the same name for the same concept (though in a different scope) in gnarly code like this is good for large-scale readability, and
  • using the blocks makes it easier for the compilers to recognize that the variables declared within may share stack frame slots. This is potentially significant if the enclosing method is also recursive.

(OK, this is all either micro-optimization, or a consequence of micro-optimization. But let's assume we've determined that it is justified.)

北陌 2024-10-16 00:46:11

是的,它们有两个用途。

首先,您可以使用此类块限制变量的范围。这有助于提高代码的可读性,因为在确定如何使用变量时需要考虑的区域较小。此外,这可以最大限度地减少方法框架所需的“槽”数量,从而节省堆栈空间。我会非常惊讶地发现这种优化是必要的。

其次,当您将标签附加到块时,可以在块内部使用目标break来跳转到块的末尾。这并不像纯粹的 goto 语句那么邪恶,但目击事件仍然会引发危险信号和警钟。

Yes, they are useful for two purposes.

First, you can limit the scope of variables using such blocks. This can help with the readability of code, because you have a smaller area to consider when determining how a variable is used. Additionally, this can minimize the required number of "slots" for the method frame, conserving stack space. I'd be very surprised to find a case where this optimization was necessary.

Second, when you attach a label to the block, a targeted break can be used inside the block to jump to the end of the block. This is not quite as evil as an unadulterated goto statement, but a sighting still triggers red flags and warning bells.

滥情稳全场 2024-10-16 00:46:11

你自己刚刚举了一个例子。您可以使 i 的声明比方法范围“更加本地化”。当它超出范围时,该方法的其余部分将看不到它。

从语法上讲,块可以出现在语句可以出现的任何地方。这是块结构语言的基本原理。

You've just given an example yourself. You can make the declaration of i 'more local' than method scope. When it goes out of scope, the rest of the method can't see it.

Syntactically, a block can appear anywhere a statement can appear. This is the fundamental principle of block-structured languages.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文