返回信息流public class Main {
public void test(Object o) {
System.out.println("Object");
}
public void test(String s) {
System.out.println("String");
}
public static void main(String[] args) {
Main that = new Main();
that.test(null);
}
}
请问输出?
答案是String
贴出来分享给大家,感受一下清华本科教育…
这是一条镜像帖。来源:北邮人论坛 / java / #52714同步于 2016/9/3
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
清华大二的Java考试题
rancho
2016/9/3镜像同步32 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
http://www.journaldev.com/9107/understanding-the-method-x-is-ambiguous-for-the-type-y-java-compilation-error-with-overloading-methods
【 在 rancho 的大作中提到: 】
: public class Main {
: public void test(Object o) {
: ...................
这种东西,想知道的话读读jls就能知道。 https://bbs.byr.cn/#!article/Java/52261
- null表达式的类型是一个特殊的null type,它是所有引用类型的子类型,总能转换成任何引用类型:https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.1
- 选择方法的时候,如果多个方法都适用,就会在编译时选取最具体的方法。 https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.2.5
但我觉得任何头脑清醒、尚且有一丝理智的程序员都不应该写这样的程序。首先,写两个方法,对互相有父子类关系的两个类型S,T分别适用,就怪怪的:根据里氏替换原则,适用于父类的方法为什么不同样地适用于子类呢?
而且还是public的,就更怪了:如果程序有一个演化更新的过程,一开始类里只有test(Object o)方法,一个客户写了程序,调用了这个test方法,但传了String参数,这时候调用的还是test(Object o);后来这个库升级了,增加了test(String s),但客户那边除非重新编译,否则仍然在调用test(Object)。JLS也专门提到了这种情况下的二进制兼容性问题(https://docs.oracle.com/javase/specs/jls/se8/html/jls-13.html#jls-13.4.23)。如果真的想对不同类有抽象、具体的两种操作,显然用面向对象的Override才对。
如果这两个test方法都是private的,而且程序员真的想为String特殊化,那么为什么不具体地写that.test((Object)null)或者that.test((String)null)呢?甚至这样写:
Object x = null;
that.test(x);
String y = null;
that.test(y);
都能保证没有歧义,而且一目了然。用Python的禅的说法:In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it.
我真的不觉得在考试中考这样的题有什么意义。真的是清华大学的考试题吗?我真想对他们伸出右手比出中指。
p.s. 我们这里上星期也刚刚考完Java,30分钟的考试,20道判断正误的题,都是很基本的Java、面向对象的概念,然后是4道编程题,有基本的循环,也有面向对象的构造、子类、重写,还有JUnit测试用例。都是在计算机上直接上机做,有IDE,可以调试。通过测试,程序正确符合要求,就给分。不会用这种边角的情况难为学生的。
我看到清华本科的cpp考题 能做上一半……(现在在清华软院读研,题是我们老师出的,本科生的考试题)
而且这种语言相关的边角的题 笔试题的选择题里有很多……做过的tx和ali的都有
发自「贵邮」