这个代码具有欺骗性,它使得编译器和我们一样变得困惑。这段代码让编译器认为catch代码块是不能到达的。对于不知情的旁观者来说,代码中并没有SQLException。所以,正确答案是:编译失败,因为编译器认为SQLException不会从try代码块中抛出-但是实际上它确实能抛出!
再次感谢Alexandru与我们分享这个问题!我们可以用另一个很酷的方式来查看代码中的错误以及SQLException实际上是怎样抛出的,这个方法是:修改catch代码块,把它修改为接收一个RuntimeException。这样你就可以看到SQLException的堆栈信息了。(实际上SQLException也并没有被catch代码段捕获,而是被虚拟机捕获并打印出异常栈的信息。)
2、问题的关键在于,是否使用了toString()
这道题只有24%的正确率,它的困难程度是这20道题中的亚军。
题目大意:这个程序的打印结果是?
a.m1 & new name
b.以上都是错误的
c.m1&m1
d.new name & new name
这道题实际上简单得多,我们只要看到第十二行,它直接打印了m1和m2,而不是m1.name和m2.name。这段代码狡猾的地方在于,当我们要打印一个对象时,Java使用的是toString方法。“name”属性是我们自己加入的,如果你忘记这点,其他地方都判断正确的话,你可能会错误地选择m1&new name这个答案。
这行代码将两个对象的name属性都赋值为”m1”。
1
m1.name = m2.name = “m1";
然后callMe方法将m2对象的name属性设置成”new name”,然后代码就结束了。
但是,这个代码片段实际上将会打印出如下信息,包括类名称以及它们的哈希码:
1
MyClass@3d0bc85 & MyClass@7d08c1b7
所以正确的答案是“None of the above”
3、Google Guava类库中的Sets
题目大意:
这道题目不妥的地方在哪?
a.不能编译
b.没有问题
c.可能造成内存溢出
d.可能造成无限循环
这个问题实际上并不特别需要关于Guava sets类库的专业知识,但却使绝大多数的开发者产生困惑。只有25%的参与者给出了正确的答案,和瞎选的正确率是一样的。
那么我们能从这段代码中看出什么呢?我们有一个方法,它返回一个集合,这个集合包含了某个人的好友圈。方法中有一个循环,它检查一个person对象的bestfriend属性是否为null。如果不为null,则将bestfriend添加到results集合里。如果一个person对象确实有一个bestfriend,那么对这个person的bestfriend,重复执行上述过程,所以我们就可以一直向bestfriend集合添加person对象,直到有一个person,它没有bestfriend,或者它的bestfriend已经在我们的result集合里了。最后这部分有一点微妙,我们不能向这个Set集合添加重复的元素,即person对象,所以这个方法并不会导致无限循环。
真正的问题在于,这段代码很有可能造成内存用尽的异常(out of memory exception)。这个循环实际上是没有边界的,所以我们可以不停地往set中添加person对象,直到内存用尽。
顺便提一下,如果你想详细了解Google Guava,可以看看我们写的这篇博客: the lesser known yet useful features about it
4、利用两个花括号进行初始化
题目大意:这段代码错误的地方在哪?
a.没有错误
b.可能获得null值
c.代码不能编译
d.打印出不正确的结果
这个问题是代码最少的问题之一,但是足以迷惑绝大部分的开发者。这道题只有26%的答题者回答正确。