美文网首页面试问题java
由两道笔试题想到的

由两道笔试题想到的

作者: imhuster | 来源:发表于2017-03-01 16:50 被阅读299次

今天有网友在群里面发了两道让他“感觉要命”的笔试题,大意如下
题目一

public class Interview{
    public static void fn(String str){System.out.println("String");}
    public static void fn(Object o){System.out.println("Object");}
    public static void main(String[] args) {
        fn(null);
    }
}
请问结果是:
A.编译出错 B.运行出错 C.输出“String” D.输出 "Object"

这道题目可以说是老掉牙了,博主最初在某Java面试宝典上看到过的这道题目,后面在Java解惑中也看到过这道题目。显然这涉及了重载方法调用的选择的问题。JLS中关于方法重载的选择是这么说的:

The remainder of the process is split into three phases, to ensure compatibility with versions of the Java programming language prior to Java SE 5.0. The phases are:

  1. The first phase (§15.12.2.2) performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the second phase.
  2. The second phase (§15.12.2.3) performs overload resolution while allowing boxing and unboxing, but still precludes the use of variable arity method invocation. If no applicable method is found during this phase then processing
    continues to the third phase.
  3. The third phase (§15.12.2.4) allows overloading to be combined with variable arity methods, boxing, and unboxing.
    If several applicable methods have been identified during one of the three phases of applicability testing, then the most specific one is chosen, as specified in section

翻译过来就是:

1.第一阶段,不允许装拆箱转换,或者变长参数,如果找不到可用的方法则执行第二阶段
2.的二阶段,执行允许装拆箱转换的重载解析,但是不允许变长参数,如果找不到可用的方法则执行第三阶段
3.第三阶段,允许重载与变长参数方法,装拆箱相结合
4.如果在任意一个阶段标识出了若干可运用的方法,则选择最具体的一个。
显然 null既可以转化为 Object 也可以转化为 String类型,确切地说“The null reference can always be assigned or cast to any reference type ”。但是String类型比Object更加具体,所以匹配String类型的方法。即选择 C
当然如果要是匹配的多个方法中一样的精确,那么则会在编译时报错

如:

public class Interview{
    public static void fn(String str){
        System.out.println("String");
    }
    public static void fn(Object o){
        System.out.println("Object");
    }
    public static void fn(Integer i){
        System.out.println("Integer");
    }
    public static void main(String[] args) {
        fn(null);
    }
}

这时,三个函数在第一阶段都可以匹配,String与Integer都比Object要更加精确匹配,但是String与Integer无法区分那个更加精确,编译器就无法判断调用那哪个方法了,因此编译出错。


题目二

public class CompoundAssignment{
    public static void main(String[] args) {
            int x = 10;
            x += x -= x -= x;
           System.out.println("x="+x);
    }
}
输出结果为?

咋一看,结合顺序从右到左,所以应该是 x+= ( x-= ( x-=x ) ) 代入数值应该是 0 += (0 -= (10 -= 10)) 结果应该为 0
好吧,我们运行一下看看
结果:

x=20

什么?怎么是20?-_- 好吧,咱们又得翻一下JLS了。
在JLS中的Example 15.26.2-2.有这么一句话“Value Of Left-Hand Side Of Compound Assignment Is Saved Before Evaluation Of Right-Hand Side”,大意是“复合赋值左端的值是在右端计算之前保存的”,所以结果应该是 10 += (10 -= (10 -= 10)) 即 20
此外为了加深对这句话的理解,在此献上JLS中的例子

class Test{
    public static void main(String[] args) {
        int k = 1;
        k += (k = 4) * (k + 2);
        System.out.println("k = "+k);   
    }
}

您看结果是多少呢?

圉于博主的水平,理解可能有所偏差,还望各位大佬不吝指正!
参考:The Java Language Specification, Java SE 8 Edition

相关文章

  • 由两道笔试题想到的

    今天有网友在群里面发了两道让他“感觉要命”的笔试题,大意如下题目一 这道题目可以说是老掉牙了,博主最初在某Java...

  • 两道js闭包题目;

    两道面试题;

  • (function(){var a = b = 3; }())

    遇到的两道笔试题:

  • 230112A 由老师的晨笔想到的

    老师的晨笔中提到了两件事:一是讲课因突发原因拉长,打乱了原先一个小时的讲课,做了临时的填充,老师自认为做了“注水”...

  • NO.32 异常处理

    java异常处理机制中的try-catch: 示例:异常捕获机制在IO中的用法 finally两道面试题 面试题1...

  • KVO使用与原理分析

    面试题目 iOS用什么方式实现对一个对象的KVO?(KVO的本质是什么?)如何手动触发KVO? 上面两道面试题目,...

  • 程序员进阶之算法练习(八)附两道搜狐笔试题

    前言 前面讲了那么多算法的重要性。口说无凭,这次带上两道搜狐今年的笔试题。这里先附上两道搜狐题目的大意:题目一:《...

  • python面试题-01

    备注:总结微信各个群中发的面试题 以下两道面试题,都涉及到python文件读写 1.请生成test1@126.co...

  • 05 iOS底层原理 - Category本质探究

    废话不多说,老规矩,还是来两道面试题: 一,Category的实现原理;二,Category和Extension的...

  • 关于类的经典面试题

    通过之前几篇文章的学习,我们已经对类做了很多的探索了,现在我们看两道面试题,巩固一下。 【面试题】类方法归属分析 ...

网友评论

    本文标题:由两道笔试题想到的

    本文链接:https://www.haomeiwen.com/subject/xvccgttx.html