【发布时间】:2010-09-17 08:30:44
【问题描述】:
多年来,我一直使用命名块来限制临时变量的范围。我从未在其他任何地方看到过这样做,这让我怀疑这是否是一个坏主意。特别是因为 Eclipse IDE 默认将这些标记为警告。
我认为,在我自己的代码中,我已经使用它取得了很好的效果。但是由于它是不习惯的,以至于优秀的程序员在看到它时会不信任它,所以我真的有两条路可以走:
- 避免这样做,或者
- 推广它,希望它成为一个成语。
示例(在更大的方法中):
final Date nextTuesday;
initNextTuesday: {
GregorianCalendar cal = new GregorianCalendar();
... // About 5-10 lines of setting the calendar fields
nextTuesday = cal.getTime();
}
这里我使用 GregorianCalendar 只是为了初始化一个日期,并且我想确保我不会意外重用它。
有些人评论说您实际上不需要命名块。虽然这是真的,但原始块看起来更像是一个错误,因为意图尚不清楚。此外,命名某些东西会鼓励您考虑块的意图。此处的目标是识别不同的代码部分,而不是为每个临时变量赋予其自己的范围。
许多人评论说最好直接使用小方法。我同意这应该是你的第一直觉。但是,可能有几个缓解因素:
- 即使考虑命名块,代码也应该是简短的一次性代码,永远不会在其他地方调用。
- 命名块是一种组织超大方法的快速方法,无需创建具有十几个参数的一次性方法。当一个类在不断变化时尤其如此,并且输入可能会因版本而异。
- 创建新方法会鼓励其重用,如果用例没有很好地建立,这可能是不明智的。命名块更容易(至少在心理上)被丢弃。
- 特别是对于单元测试,您可能需要为一次性断言定义十几个不同的对象,它们的不同之处足以让您(还)无法找到一种方法将它们整合到少数方法中,你也想不出用一英里长的名字来区分它们的方法。
使用命名作用域的优点:
- 不能意外重用临时变量
- 有限范围为垃圾收集器和 JIT 编译器提供了有关程序员意图的更多信息
- 块名称提供了对代码块的注释,我发现它比开放式 cmets 更具可读性
- 更容易将代码从大方法重构为小方法,反之亦然,因为命名块比非结构化代码更容易分离。
缺点:
不是惯用的:没有见过命名块的这种用法的程序员(即除了我之外的所有人)认为这是错误的,因为他们找不到对块名称的引用。 (就像 Eclipse 所做的那样。)让某些东西变得惯用是一场艰苦的战斗。
可以作为不良编程习惯的借口,比如:
- 制作庞大的整体方法,其中几个小方法会更清晰。
- 缩进层太深,难以阅读。
注意:我根据一些深思熟虑的回答对这个问题进行了广泛的编辑。谢谢!
【问题讨论】:
-
你实际上不需要在块上贴标签。
-
这无关,但 Sun 不推荐使用 Calendar cal = Calendar.getInstance(); ?
-
关于它是非惯用的:并非一切都必须是惯用的。一种风格是惯用的,它必须在经常出现的情况下有用。但是,您所描述的对于非常不寻常的情况是一个完美的最佳解决方案(一个代码块可以自己做,但是太小/不可重用而不能成为自己的方法。)不,并非所有事情都需要它是自己的方法,方法太多就像意大利面条太少一样。因此,总而言之,如果您足够专业,能够感受到从中受益的确切情况,请继续使用命名块,否则不要。
-
另一个注意事项:对我来说,未命名块的意图比命名块的意图要清楚得多。一个未命名的块只是说“范围限制”。一个名字只会造成更多的混乱,并导致在该块内搜索 continue/break 语句,如果没有任何代码,就会感觉不专业。
-
Eclipse(默认)会警告您“标签 initNextTuesday 从未被明确引用”。尽管可以关闭警告,但大多数开发人员不会对 Eclipse 进行个性化设置,并且可能会看到黄色曲线。我个人认为 cmets 解释你限制范围比块上的标签更好。
标签: java coding-style