1. 程式人生 > >Java-Java程式設計思想第四版 第十二章 練習

Java-Java程式設計思想第四版 第十二章 練習

練習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();
            }
        }
    }
  }
}