出自《java puzzle》
本谜题中的程序所建模的系统,将尝试着从其环境中读取一个用户ID,如果这种尝试失败了,则缺省地认为它是一个来宾用户。该程序的作者将面对有一个静态域的初始化表达式可能会抛出异常的情况。因为Java不允许静态初始化操作抛出被检查异常,所以初始化必须包装在try-finally语句块中。那么,下面的程序会打印出什么呢?
public class UnwelcomeGuest {
public static final long GUEST_USER_ID = -1;
private static final long USER_ID;
static {
try {
USER_ID = getUserIdFromEnvironment();
} catch (IdUnavailableException e) {
USER_ID = GUEST_USER_ID;
System.out.println("Logging in as guest");
}
}
private static long getUserIdFromEnvironment()
throws IdUnavailableException {
throw new IdUnavailableException();
}
public static void main(String[] args) {
System.out.println("User ID: " + USER_ID);
}
}
class IdUnavailableException extends Exception {
}
该程序看起来很直观。对getUserIdFromEnvironment的调用将抛出一个异常,从而使程序将GUEST_USER_ID(-1L)赋值给USER_ID,并打印Loggin in as guest。然后main方法执行,使程序打印User ID: -1。表象再次欺骗了我们,该程序并不能编译。如果你尝试着去编译它,你将看到和下面内容类似的一条错误信息:
UnwelcomeGuest.java:10:
variable USER_ID might already have been assigned
USER_ID = GUEST_USER_ID;
^
问题出在哪里了?USER_ID域是一个空final(blank final),它是一个在声明中没有进行初始化操作的final域[JLS 4.12.4]。很明显,只有在对USER_ID赋值失败时,才会在try语句块中抛出异常,因此,在catch语句块中赋值是相当安全的。不管怎样执行静态初始化操作语句块,只会对USER_ID赋值一次,这正是空final所要求的。为什么编译器不知道这些呢?
要确定一个程序是否可以不止一次地对一个空final进行赋值是一个很困难的问题。事实上,这是不可能的。这等价于经典的停机问题,它通常被认为是不可能解决的[Turing 36]。为了能够编写出一个编译器,语言规范在这一点上采用了保守的方式。在程序中,一个空final域只有在它是明确未赋过值的地方才可以被赋值。规范长篇大论,对此术语提供了一个准确的但保守的定义[JLS 16]。因为它是保守的,所以编译器必须拒绝某些可以证明是安全的程序。这个谜题就展示了这样的一个程序。
幸运的是,你不必为了编写Java程序而去学习那些骇人的用于明确赋值的细节。通常明确赋值规则不会有任何妨碍。如果碰巧你编写了一个真的可能会对一个空final赋值超过一次的程序,编译器会帮你指出的。只有在极少的情况下,就像本谜题一样,你才会编写出一个安全的程序,但是它并不满足规范的形式化要求。编译器的抱怨就好像是你编写了一个不安全的程序一样,而且你必须修改你的程序以满足它。
解决这类问题的最好方式就是将这个烦人的域从空final类型改变为普通的final类型,用一个静态域的初始化操作替换掉静态的初始化语句块。实现这一点的最佳方式是重构静态语句块中的代码为一个助手方法:
public class UnwelcomeGuest {
public static final long GUEST_USER_ID = -1;
private static final long USER_ID = getUserIdOrGuest;
private static long getUserIdOrGuest {
try {
return getUserIdFromEnvironment();
} catch (IdUnavailableException e) {
System.out.println("Logging in as guest");
return GUEST_USER_ID;
}
}
...// The rest of the program is unchanged
}
程序的这个版本很显然是正确的,而且比最初的版本根据可读性,因为它为了域值的计算而增加了一个描述性的名字,而最初的版本只有一个匿名的静态初始化操作语句块。将这样的修改作用于程序,它就可以如我们的期望来运行了。
总之,大多数程序员都不需要学习明确赋值规则的细节。该规则的作为通常都是正确的。如果你必须重构一个程序,以消除由明确赋值规则所引发的错误,那么你应该考虑添加一个新方法。这样做除了可以解决明确赋值问题,还可以使程序的可读性提高。
分享到:
相关推荐
尽管会员忠诚度计划广受欢迎,但实际与酒店品牌建立起长期关系的活跃会员并不多。当前,会员忠诚度计划的核心正在从单纯的积分奖励转向更深层次的宾客互动和个性化体验。 随着2020年新冠疫情对旅游业造成的巨大冲击...
在结账过程中,快速准确地处理账务,确保客人权益不受损害,这样不仅能够维护酒店的利益,更能增强客人对酒店的信任。 最后,服务员在客人离店时的告别艺术也是非常重要的一环。服务员应以热情的态度感谢客人的光临...
- **特殊天气应对**:雨雪天气下,为宾客提供雨伞服务,确保客人不受恶劣天气影响。 - **礼貌告别**:无论宾客选择何种出行方式离开,都要礼貌地告别,并表示欢迎下次光临。 #### 二、前厅服务流程及注意事项 **...
品酒会是一种独特的社交活动,主要特点是客人需自带饮料,尤其在年轻人群体中颇受欢迎。这种形式不仅降低了举办酒会的经济压力,也让聚会更频繁,增强了参与者间的互动与共享精神。在品酒会上,每个人都承担一部分...
如何撰写一篇既得体又具有吸引力的欢迎词是一门艺术,它需要考虑到场合、听众和主题的契合,避免过于平淡或过于正式,以确保宾客感到受到重视和欢迎。 【导游欢迎词的特点】 对于导游来说,出团欢迎词不仅需要表达...
大型茶会作为一项传统与现代社交文化相结合的活动,受到越来越多的组织和参与者欢迎。在这样的场合下,对礼仪的掌握不仅体现了主办者的专业素养,而且直接关系到参与者对活动的整体印象。大型茶会的礼仪规则涉及到...
第九页的“欢迎你的到来”通过温馨的措辞欢迎宾客,营造出一个热情好客的氛围;而第十页的“感谢您的观看”则作为结束语,表达了对阅读邀请函宾客的感激之情,同时也给整个邀请函画上了一个圆满的句号。 总之,...
《卓越值班经理服务手册》中提到的“三步服务程序”,即热情欢迎、预期与服从、礼貌送行,是提升宾客体验的关键。同时,标准的待客礼仪,如注目礼和欠身礼,也是值班经理必须掌握的基本技能。注目礼要求在适当的距离...
规范、系统的服务礼仪培训不仅能够塑造服务人员的专业形象,还能培养出受客户欢迎的服务技巧,增强企业的竞争力。 服务人员学习和应用服务礼仪,不仅是提升个人职业形象的必要条件,也是企业提高效率、增强市场竞争...
【婚礼来宾致贺词】是婚礼仪式中一个重要的环节,它是对新人的祝福与期许的表达,也是向宾客展示敬意的一种方式。...在准备婚礼课件时,这个环节应当受到足够的重视,以确保婚礼仪式的顺利进行和宾客的满意体验。
众所周知,婚礼倒彩砂仪式是近年来在婚庆文化中颇受欢迎的一个环节。它起源于一个美丽的故事:海洋中两粒沙子,无论潮起潮落,风卷浪涌,它们始终相依相偎,不离不弃,象征着真爱的永恒不变。倒彩砂仪式,就是将两种...
证婚人通常由新人信任且受尊重的人担任,他们在婚礼上正式宣布新人的婚姻合法有效,并向新人及宾客传达祝福。 1. **证婚人的角色**: - 证婚人是婚礼仪式中的关键人物,他们在法律上有权证明新人的婚姻关系,确保...
在正餐后的酒会,虽然不是必须提供食物,但如有提供会更受欢迎。然而,考虑到大多数客人可能刚用过餐,食物不宜过早出现。理想的酒会食物应该是易于食用且能刺激食欲的,比如各种果仁、鸡尾酒软饼、泡菜、长面包、...
上班时间不应扎堆闲聊、使用手机做私事,更不能对宾客不尊重,如不理问、大声喧哗或表现出不雅行为。违反这些规则将被扣2-5分。对待顾客应始终保持礼貌,不得有与客人赌气、争吵、讲脏话等行为,否则将面临更严厉的...
其受欢迎的热度随着人们健康饮食意识的增强而持续升温,乌骨鸡也成为了一种标志性的健康食品。 乌骨鸡的食用和文化价值是无法割裂的。在我国,乌骨鸡不仅仅是一种食材,它在许多地区还承载着风俗和文化。比如,许多...
因此,主人应以热情的态度款待每一位客人,让他们感受到被重视和欢迎。 其次,宴请的环境至关重要。一个宽敞舒适、空气流通、光线适宜的用餐空间,可以让客人放松心情,更好地享受聚会的乐趣。如果场地狭窄、闷热,...
开场白中,司仪自我介绍并表示荣幸能主持这场婚礼,同时也代表新人及家人向宾客表达感激和欢迎之情。 2. **新人爱情故事**: 在新人入场前,司仪讲述新人的爱情故事,增加婚礼的情感深度,让宾客更深入了解这对...
1. **开场白**:主持人的开场通常是对宾客的欢迎和自我介绍,比如“各位来宾、各位亲朋好友、女士们先生们”,以及对新人的简单介绍,如“非常荣幸受到我们尊敬的余总的委托,在这里主持 xx 小姐和 xx 先生的婚礼”...
这一刻,不仅仅是新人的幸福,更是所有在场宾客的幸福。 随后是传统的“拜天地”环节,新人向天地、日月、四季献上敬意,体现了新人对自然和生命的尊重与敬畏。这一环节不仅是对传统文化的传承,也是对未来的美好祈...
- **电子请柬**:随着科技的发展,电子请柬越来越受欢迎,可以通过电子邮件、微信、QQ等方式发送,环保且快捷。 - **传统纸质请柬**:如果选择纸质请柬,要确保纸张质量好,印刷清晰,还可以添加一些装饰,如丝带...