Java-Java程式設計思想第四版 第十二章 練習
阿新 • • 發佈:2018-12-25
練習1:
/* Create a class with a main(0 that throws an object of class Exception * inside a try block. Give the constructor for Exception a String argument. * Catch the exception inside a catch clause and print the String argument. * Add a finally clause and print a message to prove you were there. */ import java.util.*; import static net.mindview.util.Print.*; public class Ja12_4_1{ public static void main(String[] args){ try{ throw new Exception("Originating from Exception"); }catch(Exception e){ e.printStackTrace(System.out); }finally{ print("it is executed"); } } } /* java.lang.Exception: Originating from Exception at Ja12_4_1.main(Ja12_4_1.java:12) it is executed*/
練習2:
/* Define an object reference and initialize it to null. Try to call a method * through this reference. Now wrap the code in a try-catch clause to catch the * exception. */ public class Ja12_4_2{ private static Integer i=null; public static void main(String[] args){ try{ i.toString(); }catch(NullPointerException e){ e.printStackTrace(System.out); } } }
練習3:
// Write code to generate and catch an ArrayIndexOutOfBoundsException. public class Ja12_4_3{ private static int[] a=new int[2]; public static void main(String[] args){ try{ a[2]=3; }catch(ArrayIndexOutOfBoundsException e){ e.printStackTrace(System.out); } } }
練習4:
/* Create your own exception class using the extends keyword. Write a * constructor for this class that takes a String argument and stores it inside * the object with a String reference. Write a method that displays the stored * String. Create a try-catch clause to exercise your new exception. */ import static net.mindview.util.Print.*; class AException extends Exception{ private String a; AException(){} AException(String a){super(a);this.a=a;} void show(){print("it's another method: "+a);} } public class Ja12_4_4{ public static void main(String[] args){ try{ throw new AException("it's wrong"); }catch(AException e){ e.printStackTrace(System.out); e.show(); } } }
練習5:
/* Create you own resumption-like behavior using a while loop that repeats * until an exception is no longer thrown. */ import static net.mindview.util.Print.*; public class Ja12_4_5{ private static int[] a=new int[2]; public static void main(String[] args){ int x=5; while(true){ try{ a[x]=5; print("trying..."); break; }catch(ArrayIndexOutOfBoundsException e){ e.printStackTrace(System.out); x--; }finally{ print("no final..."); } } print("i'm out!"); } }
練習6:
/* Create two exception classes, each of which performs its own logging * automtically. Demonstrate that these work. */ import java.util.logging.*; import java.io.*; class Exception1 extends Exception{ private static Logger logger=Logger.getLogger("hjk"); Exception1(){ StringWriter trace=new StringWriter(); printStackTrace(new PrintWriter(trace));//把printStackTrace的內容給了trace logger.severe(trace.toString()); } } class Exception2 extends Exception{} public class Ja12_4_6{ public static void main(String[] args){ try{ throw new Exception1(); }catch(Exception1 e){ e.printStackTrace(System.out); } } } /*三月 09, 2018 4:53:26 下午 Exception1 <init> 嚴重: Exception1 at Ja12_4_6.main(Ja12_4_6.java:18) Exception1 at Ja12_4_6.main(Ja12_4_6.java:18)*/
練習7:
// Modify Exercise 3 so that the catch clause logs the result. import java.util.logging.*; import java.io.*; public class Ja12_4_7{ private static int[] a=new int[2]; private static Logger logger=Logger.getLogger("Ja12_4_7"); static void logException(Exception e){ StringWriter trace=new StringWriter(); e.printStackTrace(new PrintWriter(trace)); logger.severe(trace.toString()); } public static void main(String[] args){ try{ a[2]=3; }catch(ArrayIndexOutOfBoundsException e){ e.printStackTrace();//System.out); System.err.println("Caught ArrayIndexOutOfBoundsException"); logException(e); } } } /*java.lang.ArrayIndexOutOfBoundsException: 2 at Ja12_4_7.main(Ja12_4_7.java:14) Caught ArrayIndexOutOfBoundsException 三月 09, 2018 5:02:21 下午 Ja12_4_7 logException 嚴重: java.lang.ArrayIndexOutOfBoundsException: 2 at Ja12_4_7.main(Ja12_4_7.java:14)*/
練習8:
/* Write a class with a method that throws an exception of the type created * in Exercise 4. Try compiling it without an exception specification to see * what the compiler says. Add the appropriate exception specification. Try * out your class and its exception inside a try-catch clause. */ class Exception1 extends Exception{} public class Ja12_5_8{ static void a() throws Exception1{ throw new Exception1(); } public static void main(String[] args) { try{ a(); }catch(Exception e){ System.err.println("ok"); } } }
練習9:
/* Create three new types of exceptions. Write a class with a method that * throws all three. In main(), call the method but only use a single catch * clause that will catch all three types of exceptions. */ class Exception1 extends Exception{} class Exception2 extends Exception{} class Exception3 extends Exception{} public class Ja12_6_9{ public static void main(String[] args){ try{ //throw new Exception1(); //throw new Exception2(); throw new Exception3(); }catch(Exception e){e.printStackTrace(System.out);} } }
練習10,11:
/* Create a class with two methods, f() and g(). In g(), throw an exception of * a new type that you define. In f(), call g(), catch its exception and, in the * catch clause, throw a different exception (of a second type that you define). * Test your code in main(). */ /* Repeat the previous exercise, but inside the catch clause, wrap g()'s * exception in a RuntimeException. */ class Exception1 extends Exception{} class Exception2 extends Exception{} public class Ja12_6_10{ private static void g() throws Exception1{ throw new Exception1(); } private static void f(){ try{ try{ g(); }catch(Exception1 e){ e.printStackTrace(); throw new RuntimeException(); } }catch(RuntimeException re){ re.printStackTrace(); } } public static void main(String[] args){ f(); } } /*Exception1 at Ja12_6_10.g(Ja12_6_10.java:13) at Ja12_6_10.f(Ja12_6_10.java:18) at Ja12_6_10.main(Ja12_6_10.java:28) java.lang.RuntimeException at Ja12_6_10.f(Ja12_6_10.java:21) at Ja12_6_10.main(Ja12_6_10.java:28)*/
練習12:
/* Modify innerclasses/Sequence.java so that it throws an appropriate * exception if you try to put in too many elements. */ interface Selector { boolean end(); Object current(); void next(); } class ElementTooMuchException extends Exception{} public class Ja12_7_12 { private Object[] items; private int next = 0; public Ja12_7_12(int size){items = new Object[size]; } public void add(Object x) throws ElementTooMuchException{ if(next < items.length) items[next++] = x; if(next==items.length){throw new ElementTooMuchException();} } private class SequenceSelector implements Selector { private int i = 0; public boolean end() { return i == items.length; } public Object current() { return items[i]; } public void next() { if(i < items.length) i++; } } public Selector selector() { return new SequenceSelector(); } public static void main(String[] args) { try{ Ja12_7_12 sequence = new Ja12_7_12(10); for(int i = 0; i < 10; i++) sequence.add(Integer.toString(i)); Selector selector = sequence.selector(); while(!selector.end()) { System.out.print(selector.current() + " "); selector.next(); } }catch(ElementTooMuchException e){ e.printStackTrace(); } } }
練習14:
// Show that the OnOffSwitch.java can fail by throwing a // RuntimeException inside the try block. import static net.mindview.util.Print.*; class Switch { private boolean state = false; public boolean read() { return state; } public void on() { state = true; print(this); } public void off() { state = false; print(this); } public String toString() { return state ? "on" : "off"; } } class OnOffException1 extends Exception{} class OnOffException2 extends Exception{} public class Ja12_8_14 { private static Switch sw = new Switch(); public static void f() throws OnOffException1,OnOffException2 {} public static void main(String[] args) { try { sw.on(); // Code that can throw exceptions... f(); throw new RuntimeException(); sw.off(); } catch(OnOffException1 e) { System.out.println("OnOffException1"); sw.off(); } catch(OnOffException2 e) { System.out.println("OnOffException2"); sw.off(); } } } /*Ja12_8_14.java:23: 錯誤: 無法訪問的語句 sw.off(); ^ 1 個錯誤 shell returned 1*/
練習15:
// Show that WithFinally.java doesn't fail by throwing a // RuntimeException inside the try block. import static net.mindview.util.Print.*; class Switch { private boolean state = false; public boolean read() { return state; } public void on() { state = true; print(this); } public void off() { state = false; print(this); } public String toString() { return state ? "on" : "off"; } } class OnOffException1 extends Exception{} class OnOffException2 extends Exception{} public class Ja12_8_15 { static Switch sw = new Switch(); public static void f() throws OnOffException1,OnOffException2 {} public static void main(String[] args) { try { sw.on(); // Code that can throw exceptions... f(); throw new RuntimeException(); } catch(OnOffException1 e) { System.out.println("OnOffException1"); } catch(OnOffException2 e) { System.out.println("OnOffException2"); } finally { sw.off(); } } }
練習16:
// MOdify reusing/CADSystem.java to demonstrate that returning from the // middle of a try-finally will still perform proper cleanup. import static net.mindview.util.Print.*; class Shape { Shape(int i) { print("Shape constructor"); } void dispose() { print("Shape dispose"); } } class Circle extends Shape { Circle(int i) { super(i); print("Drawing Circle"); } void dispose() { print("Erasing Circle"); super.dispose(); } } class Triangle extends Shape { Triangle(int i) { super(i); print("Drawing Triangle"); } void dispose() { print("Erasing Triangle"); super.dispose(); } } class Line extends Shape { private int start, end; Line(int start, int end) { super(start); this.start = start; this.end = end; print("Drawing Line: " + start + ", " + end); } void dispose() { print("Erasing Line: " + start + ", " + end); super.dispose(); } } public class Ja12_8_16 extends Shape { private Circle c; private Triangle t; private Line[] lines = new Line[3]; public Ja12_8_16(int i) { super(i + 1); for(int j = 0; j < lines.length; j++) lines[j] = new Line(j, j*j); c = new Circle(1); t = new Triangle(1); print("Combined constructor"); } public void dispose() { print("Ja12_8_16.dispose()"); // The order of cleanup is the reverse // of the order of initialization: t.dispose(); c.dispose(); for(int i = lines.length - 1; i >= 0; i--) lines[i].dispose(); super.dispose(); } public static void main(String[] args) { Ja12_8_16 x = new Ja12_8_16(47); try { // Code and exception handling... return; } finally { x.dispose(); } } }
練習18:
// Add a second level of exception loss to LostMessage.java so that the // HoHumException is itself replaced by a third exception. class VeryImportantException extends Exception { public String toString() { return "A very important exception!"; } } class HoHumException extends Exception { public String toString() { return "A trivial exception"; } } class Exception3 extends Exception{} public class Ja12_8_18 { void f() throws VeryImportantException { throw new VeryImportantException(); } void dispose() throws HoHumException { throw new HoHumException(); } public static void main(String[] args) { try { Ja12_8_18 lm = new Ja12_8_18(); try { lm.f(); } finally { try{ lm.dispose(); } finally{ throw new Exception3(); } } } catch(Exception e) { System.out.println(e); } } }
練習19:
// Repair the problem in LostMessage.java by guarding the call in the // finally clause. class VeryImportantException extends Exception { public String toString() { return "A very important exception!"; } } class HoHumException extends Exception { public String toString() { return "A trivial exception"; } } public class Ja12_8_19 { void f() throws VeryImportantException { throw new VeryImportantException(); } void dispose() throws HoHumException { throw new HoHumException(); } public static void main(String[] args) { try { Ja12_8_19 lm = new Ja12_8_19(); try { lm.f(); }catch(VeryImportantException e){ System.err.println(e); } finally { lm.dispose(); } } catch(Exception e) { System.out.println(e); } } }
練習20:
/* MOdify Ja12_9_20.java by adding an UmpireArgument exception type * and methods that throw this exception. Test the modified hierarchy. */ class BaseballException extends Exception {} class Foul extends BaseballException {} class Strike extends BaseballException {} class UmpireArgument extends BaseballException{} abstract class Inning { public Inning() throws BaseballException {} public void event() throws BaseballException { // Doesn't actually have to throw anything } public abstract void atBat() throws Strike, Foul; public void walk() {} // Throws no checked exceptions public abstract void f() throws UmpireArgument; } class StormException extends Exception {} class RainedOut extends StormException {} class PopFoul extends Foul {} interface Storm { public void event() throws RainedOut; public void rainHard() throws RainedOut; } public class Ja12_9_20 extends Inning implements Storm { // OK to add new exceptions for constructors, but you // must deal with the base constructor exceptions: public Ja12_9_20() throws RainedOut, BaseballException {} public Ja12_9_20(String s) throws Foul, BaseballException {} // Regular methods must conform to base class: //! void walk() throws PopFoul {} //Compile error // Interface CANNOT add exceptions to existing // methods from the base class: //! public void event() throws RainedOut {} // If the method doesn't already exist in the // base class, the exception is OK: public void rainHard() throws RainedOut {} // You can choose to not throw any exceptions, // even if the base version does: public void event() {} // Overridden methods can throw inherited exceptions: public void atBat() throws PopFoul {} public void f() throws UmpireArgument{throw new UmpireArgument();} public static void main(String[] args) { try { Ja12_9_20 si = new Ja12_9_20(); si.atBat(); si.f(); } catch(PopFoul e) { System.out.println("Pop foul"); } catch(RainedOut e) { System.out.println("Rained out"); } catch(BaseballException e) { System.out.println("Generic baseball exception"); } // Strike not thrown in derived version. try { // What happens if you upcast? Inning i = new Ja12_9_20(); i.atBat(); // You must catch the exceptions from the // base-class version of the method: } catch(Strike e) { System.out.println("Strike"); } catch(Foul e) { System.out.println("Foul"); } catch(RainedOut e) { System.out.println("Rained out"); } catch(BaseballException e) { System.out.println("Generic baseball exception"); } } }
練習21:
// Demonstrate that a derived-class constructor cannot catch exceptions thrown // by its base-class constructor. class E1 extends Exception{} class A{ A() throws E1{ throw new E1(); } } public class Ja12_10_21 extends A{ Ja12_10_21() throws E1{ try{ try{ throw new Exception(); }catch(Exception ee){ System.out.println("in Ja().Exception"); } A a=new A(); }catch(E1 e){ System.out.println("in Ja()"); e.printStackTrace(); } } public static void main(String[] args){ try{ Ja12_10_21 ja=new Ja12_10_21(); }catch(E1 e){ System.out.println("in main()"); e.printStackTrace(); } } } /*基類丟擲異常後,直接終止了對派生類構造器的呼叫*/
練習22:
/* Create a class called FailingConstructor with a constructor that might fail * partway through the construction process and throw an exception. In main(), * write code that properly guards against this failure. */ class FailingConstructor{ FailingConstructor() throws Exception{ throw new Exception(); } } public class Ja12_10_22{ public static void main(String[] args){ try{ FailingConstructor fc=new FailingConstructor(); }catch(Exception e){ e.printStackTrace(); } } }
練習24:
/* Add a dipsose() method to the FailingConstructor class and write code to properly use * this class. */ import java.io.*; import static net.mindview.util.Print.*; class InputFile{ private BufferedReader in; InputFile(String fname){ try{ in=new BufferedReader(new FileReader(fname)); }catch(IOException ioe){ ioe.printStackTrace(); }catch(Exception e){ try{ in.close(); }catch(IOException ioe){ ioe.printStackTrace(); } throw e; }finally{ } } public void dispose(){ try{ in.close(); }catch(IOException e){ throw new RuntimeException("closed failed"); } } public String getLine(){ String s; try{ s=in.readLine(); }catch(IOException e){ throw new RuntimeException("readline failed"); } return s; } } public class Ja12_10_24{ public static void main(String[] args){ try{ InputFile in=new InputFile("Ja12_10_23.java"); try{ while((in.getLine())!=null)print(1); }catch(Exception e){ e.printStackTrace(); }finally{ in.dispose(); } }catch(Exception e){ e.printStackTrace(); } } }
練習25:
/* Create a three-level hierarchy of exceptions. Now create a * base-class A with a method that throws an exception at the base * of your hierarchy. Inherit B from A and override the method so * it throws an exception at level two of your hierarchy. Repeat by * inheriting class C from B. In main(), create a C and upcast it * to A, then call the method. */ class E1 extends Exception{} class E2 extends E1{} class E3 extends E2{} class A{ void f() throws E1{ throw new E1(); } } class B extends A{ void f() throws E2{ throw new E2(); } } class C extends B{ void f() throws E3{ throw new E3(); } } public class Ja12_11_25{ public static void main(String[ ] args){ A c=new C(); try{ c.f(); }catch(Exception e){e.printStackTrace();} } } //最後輸出的還是C的異常E3
練習27:
// Modify Exercise 3 to convert the exception to a Runtime Exception. public class Ja12_12_27{ private static int[] a=new int[2]; public static void main(String[] args){ try{ a[2]=3; }catch(ArrayIndexOutOfBoundsException e){ throw new RuntimeException(e); } } }
練習28;
/* Modify Exercise 4 so that the custom exception class inherits from * RuntimeException, and show that the compiler allows you to leave * out the try block. */ import static net.mindview.util.Print.*; class AException extends RuntimeException{ private String a; AException(){} AException(String a){super(a);this.a=a;} void show(){print("it's another method: "+a);} } public class Ja12_12_28{ public static void main(String[] args){ throw new AException("it's wrong"); } }
練習29;
/* Modify all the exception types in Ja12_12_29.java so that they extend * RuntimeException, and show that no exception specifications or try blocks * are necessary. Remove the '//!' comments and show how the methods can be * compiled without specifications. */ class BaseballException extends RuntimeException {} class Foul extends BaseballException {} class Strike extends BaseballException {} abstract class Inning { public Inning() throws BaseballException {} public void event() throws BaseballException { // Doesn't actually have to throw anything } public abstract void atBat() throws Strike, Foul; public void walk() {} // Throws no checked exceptions } class StormException extends RuntimeException {} class RainedOut extends StormException {} class PopFoul extends Foul {} interface Storm { public void event() throws RainedOut; public void rainHard() throws RainedOut; } public class Ja12_12_29 extends Inning implements Storm { // OK to add new exceptions for constructors, but you // must deal with the base constructor exceptions: public Ja12_12_29() throws RainedOut, BaseballException {} public Ja12_12_29(String s) throws Foul, BaseballException {} // Regular methods must conform to base class: public void walk() throws PopFoul {} //Compile error // Interface CANNOT add exceptions to existing // methods from the base class: public void event() throws RainedOut {} // If the method doesn't already exist in the // base class, the exception is OK: public void rainHard() throws RainedOut {} // You can choose to not throw any exceptions, // even if the base version does: // public void event() {} // Overridden methods can throw inherited exceptions: public void atBat() throws PopFoul {} public static void main(String[] args) { try { Ja12_12_29 si = new Ja12_12_29(); si.atBat(); } catch(PopFoul e) { System.out.println("Pop foul"); } catch(RainedOut e) { System.out.println("Rained out"); } catch(BaseballException e) { System.out.println("Generic baseball exception"); } // Strike not thrown in derived version. try { // What happens if you upcast? Inning i = new Ja12_12_29(); i.atBat(); // You must catch the exceptions from the // base-class version of the method: } catch(Strike e) { System.out.println("Strike"); } catch(Foul e) { System.out.println("Foul"); } catch(RainedOut e) { System.out.println("Rained out"); } catch(BaseballException e) { System.out.println("Generic baseball exception"); } } }
練習30:
/* Modify Ja12_12_30.java so that the exceptions inherit from * RuntimeException. Modify main() so that the technique * in TurnOffChecking.java is used to handle the different * types of exceptions. */ import exceptions.*; class SomeOtherException extends Exception{} class Annoyance extends RuntimeException {} class Sneeze extends Annoyance {} class WrapCheckedException { void throwRuntimeException(int type) { try { switch(type) { case 0: throw new Sneeze(); case 1: throw new Annoyance(); case 2: throw new RuntimeException("Where am I?"); default: return; } } catch(Exception e) { // Adapt to unchecked: throw new RuntimeException(e); } } } public class Ja12_12_30 { public static void main(String[] args) { // Catch the exact type: WrapCheckedException wc=new WrapCheckedException(); for(int i=0;i<4;i++){ try { if(i<3) wc.throwRuntimeException(i); else throw new SomeOtherException(); } catch(SomeOtherException s) { s.printStackTrace(); }catch(RuntimeException r){ try{ throw r.getCause(); }catch(Sneeze s){ s.printStackTrace(); }catch(Annoyance a){ a.printStackTrace(); }catch(Throwable e){ e.printStackTrace(); } } } } }