谜题36:优柔寡断
下面的程序打印的是什么呢?甚至,它是合法的吗?- publicclassIndecisive{
- publicstaticvoidmain(String[]args){
- System.out.println(decision());
- }
- staticbooleandecision(){
- try{
- returntrue;
- }finally{
- returnfalse;
- }
- }
- }
谜题37:极端不可思议
下面的三个程序每一个都会打印些什么?不要假设它们都可以通过编译。- importjava.io.IOException;
- publicclassArcane1{
- publicstaticvoidmain(String[]args){
- try{
- System.out.println("Helloworld");
- }catch(IOExceptione){
- System.out.println("I'veneverseenprintlnfail!");
- }
- }
- }
- publicclassArcane2{
- publicstaticvoidmain(String[]args){
- try{
- //Ifyouhavenothingnicetosay,saynothing
- }catch(Exceptione){
- System.out.println("Thiscan'thappen");
- }
- }
- }
- interfaceType1{
- voidf()throwsCloneNotSupportedException;
- }
- interfaceType2{
- voidf()throwsInterruptedException;
- }
- interfaceType3extendsType1,Type2{
- }
- publicclassArcane3implementsType3{
- publicvoidf(){
- System.out.println("Helloworld");
- }
- publicstaticvoidmain(String[]args){
- Type3t3=newArcane3();
- t3.f();
- }
- }
第二个程序能通过编译,但不会打印任何东西。虽然try里面没有抛出任何异常,但捕获unchecked exception是可以的。
第三个程序可以打印Hello World。这里涉及到子类在复写方法的时候需要怎么处理父类声明的Exception问题。子类只是不可以扩大父类声明的Exception范围。
谜题38:不受欢迎的宾客
本谜题中的程序所建模的系统,将尝试着从其环境中读取一个用户ID,如果这种尝试失败了,则缺省地认为它是一个来宾用户。该程序的作者将面对有一个静态域的初始化表达式可能会抛出异常的情况。因为Java不允许静态初始化操作抛出被检查异常,所以初始化必须包装在try-finally语句块中。那么,下面的程序会打印出什么呢?- publicclassUnwelcomeGuest{
- publicstaticfinallongGUEST_USER_ID=-1;
- privatestaticfinallongUSER_ID;
- static{
- try{
- USER_ID=getUserIdFromEnvironment();
- }catch(IdUnavailableExceptione){
- USER_ID=GUEST_USER_ID;
- System.out.println("Logginginasguest");
- }
- }
- privatestaticlonggetUserIdFromEnvironment()
- throwsIdUnavailableException{
- thrownewIdUnavailableException();
- }
- publicstaticvoidmain(String[]args){
- System.out.println("UserID:"+USER_ID);
- }
- }
- classIdUnavailableExceptionextendsException{
- }
对于final的变量,编译器很难确定它是否已经被赋值了。除非它明确地看到没有赋值的地方。
谜题39:您好,再见!
下面的程序打印什么?- publicclassHelloGoodbye{
- publicstaticvoidmain(String[]args){
- try{
- System.out.println("Helloworld");
- System.exit(0);
- }finally{
- System.out.println("Goodbyeworld");
- }
- }
- }
- publicclassHelloGoodbye1{
- publicstaticvoidmain(String[]args){
- System.out.println("Helloworld");
- Runtime.getRuntime().addShutdownHook(
- newThread(){
- publicvoidrun(){
- System.out.println("Goodbyeworld");
- }
- });
- System.exit(0);
- }
- }
谜题40:不情愿的构造器
尽管在一个方法声明中看到一个throws子句是很常见的,但是在构造器的声明中看到一个throws子句就很少见了。下面的程序就有这样的一个声明。那么,它将打印出什么呢?- publicclassReluctant{
- privateReluctantinternalInstance=newReluctant();
- publicReluctant()throwsException{
- thrownewException("I'mnotcomingout");
- }
- publicstaticvoidmain(String[]args){
- try{
- Reluctantb=newReluctant();
- System.out.println("Surprise!");
- }catch(Exceptionex){
- System.out.println("Itoldyouso");
- }
- }
- }
- publicclassReluctant{
- privateReluctantinst=newReluctant();
- publicstaticvoidmain(String[]args){
- Reluctantr=newReluctant();
- }
- }
谜题41:域和流
这个程序试图把数据从源文件流拷贝到目标文件流,然后关闭所有它打开的流,哪怕它遇到异常。它能正常处理吗?- staticvoidcopy(Stringsrc,Stringdest)throwsIOException{
- InputStreamin=null;
- OutputStreamout=null;
- try{
- in=newFileInputStream(src);
- out=newFileOutputStream(dest);
- byte[]buf=newbyte[1024];
- intn;
- while((n=in.read(buf))>0)
- out.write(buf,0,n);
- }finally{
- if(in!=null)in.close();
- if(out!=null)out.close();
- }
- }
对于稀缺资源,比如连接池,流,像下面这样关闭他们,几乎是必须的。
- finally{
- if(in!=null){
- try{
- in.close();
- }catch(IOExceptionex){
- //Thereisnothingwecandoifclosefails
- }
- if(out!=null)
- try{
- out.close();
- }catch(IOExceptionex){
- //Thereisnothingwecandoifclosefails
- }
- }
- }
谜题42:异常为循环而抛
下面的程序大意是,对多维数组中的每一个数组,检查他们是否满足thirdElementIsThree这个规则。下面的程序正确吗?- publicclassLoop{
- publicstaticvoidmain(String[]args){
- int[][]tests={{6,5,4,3,2,1},{1,2},
- {1,2,3},{1,2,3,4},{1}};
- intsuccessCount=0;
- try{
- inti=0;
- while(true){
- if(thirdElementIsThree(tests[i++]))
- successCount++;
- }
- }catch(ArrayIndexOutOfBoundsExceptione){
- //Nomoreteststoprocess
- }
- System.out.println(successCount);
- }
- privatestaticbooleanthirdElementIsThree(int[]a){
- returna.length>=3&a[2]==3;
- }
- }
1 用了恐怖的while(true)作循环;
2 用catch Exception来做为退出循环的条件;
3 错误地使用了&;
谜题43:异常地危险
请写出一个程序, 程序里面会抛出没有被catch住的checked exception, 但是不会被编辑器拒绝.
有两种方法可以实现, 1是利用了Class.newInstance方法, 该方法会调用无参的构造函数, 如果该构造函数抛出checked exception的话, 编译器是检测不到的.
- publicclassThrower{
- publicThrower()throwsIOException{
- thrownewIOException();
- }
- publicstaticvoidmain(String[]args)
- throwsInstantiationException,IllegalAccessException{
- Throwerthrower=Thrower.class.newInstance();
- }
- }
第二种方式是利用了泛型.
- classTigerThrower<TextendsThrowable>{
- publicstaticvoidsneakyThrow(Throwablet){
- newTigerThrower<Error>().sneakyThrow2(t);
- }
- privatevoidsneakyThrow2(Throwablet)throwsT{
- throw(T)t;
- }
- publicstaticvoidmain(String[]args){
- sneakyThrow(newIOException());
- }
- }
谜题45:令人疲惫不堪的测验
本谜题将测试你对递归的了解程度。下面的程序将做些什么呢?
- publicclassWorkout{
- publicstaticvoidmain(String[]args){
- workHard();
- System.out.println("It'snaptime.");
- }
- privatestaticvoidworkHard(){
- try{
- workHard();
- }finally{
- workHard();
- }
- }
- }
Java虚拟机对栈的深度限制到了某个预设的水平。当超过这个水平时,VM就抛出StackOverflowError。为了让我们能够更方便地考虑程序的行为,我们假设栈的深度为3,这比它实际的深度要小得多。现在让我们来跟踪其执行过程。
main方法调用workHard,而它又从其try语句块中递归地调用了自己,然后它再一次从其try语句块中调用了自己。在此时,栈的深度是3。当workHard方法试图从其try语句块中再次调用自己时,该调用立即就会以StackOverflowError而失败。这个错误是在最内部的finally语句块中被捕获的,在此处栈的深度已经达到了3。在那里,workHard方法试图递归地调用它自己,但是该调用却以StackOverflowError而失败。这个错误将在上一级的finally语句块中被捕获,在此处站的深度是2。该finally中的调用将与相对应的try语句块具有相同的行为:最终都会产生一个StackOverflowError。这似乎形成了一种模式,而事实也确实如此。
那么,究竟大到什么程度呢?有一个快速的试验表明许多VM都将栈的深度限制为1024,因此,调用的数量就是1+2+4+8…+21,024=2^1,025-1,而抛出的异常的数量是2^1,024。假设我们的机器可以在每秒钟内执行1010个调用,并产生1010个异常,按照当前的标准,这个假设的数量已经相当高了。在这样的假设条件下,程序将在大约1.7×10291年后终止。为了让你对这个时间有直观的概念,我告诉你,我们的太阳的生命周期大约是1010年,所以我们可以很确定,我们中没有任何人能够看到这个程序终止的时刻。尽管它不是一个无限循环,但是它也就算是一个无限循环吧。
原文地址:http://blog.csdn.net/sunxing007/article/details/9090319