// exceptions/Ex1.java
// TIJ4 Chapter Exceptions, Exercise 1, page 452
/* 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.
*/
class Exception1 extends Exception {
public Exception1(String msg) {
super(msg);
System.out.println("Exception1(String msg)");
}
}
public class Ex1 {
public static void f() throws Exception1 {
System.out.println("Throwing MyException from f()");
throw new Exception1("From f()");
}
public static void main(String[] args) {
try {
f();
} catch(Exception1 e) {
System.err.println("Caught Exception1");
e.printStackTrace();
} finally {
System.out.println("Made it to finally");
}
}
}
// exceptions/Ex2.java
// TIJ4 Chapter Exceptions, Exercise 2, page 452
/* 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 Ex2 {
private static Integer i = null;
public static void main(String[] args) {
// leads to NullPointerException:
// System.out.println(i.toString());
try {
System.out.println(i.toString());
} catch(NullPointerException e) {
System.err.println("Caught NullPointerException");
e.printStackTrace();
}
try {
i = 10;
System.out.println(i.toString());
} catch(NullPointerException e) {
System.err.println("Caught NullPointerException");
e.printStackTrace();
} finally {
System.out.println("Got through it");
}
}
}
// exceptions/Ex3.java
// TIJ4 Chapter Exceptions, Exercise 3, page 452
// Write code to generate and catch an ArrayIndexOutOfBoundsException.
public class Ex3 {
private static int[] ia = new int[2];
public static void main(String[] args) {
try {
ia[2] = 3;
} catch(ArrayIndexOutOfBoundsException e) {
System.err.println(
"Caught ArrayIndexOutOfBoundsException");
e.printStackTrace();
}
}
}
// exceptions/Ex4.java
// TIJ4 Chapter Exceptions, Exercise 4, page 452
/* 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.
*/
class Exception4 extends Exception {
private String msg;
Exception4(String msg) {
super(msg);
System.out.println("Exception4()");
this.msg = msg;
}
protected void showS() {
System.out.println("Message from Exception4: " + msg);
}
}
public class Ex4 {
public static void f() throws Exception4 {
System.out.println("f()");
throw new Exception4("Ouch from f()");
}
public static void main(String[] args) {
try {
f();
} catch(Exception4 e) {
System.err.println("Caught Exception4");
e.printStackTrace();
e.showS();
}
}
}
// exceptions/Ex5.java
// TIJ4 Chapter Exceptions, Exercise 5, page 452
/* Create you own resumption-like behavior. using a while loop that repeats
* until an exception is no longer thrown.
*/
public class Ex5 {
private static int[] ia = new int[2];
static int x = 5;
public static void main(String[] args) {
while(true) {
try {
ia[x] = 1;
System.out.println(ia[x]);
break;
} catch(ArrayIndexOutOfBoundsException e) {
System.err.println(
"Caught ArrayIndexOutOfBoundsException");
e.printStackTrace();
x--;
} finally {
System.out.println("Are we done yet?");
}
}
System.out.println("Now, we're done.");
}
}
// exceptions/Ex6.java
// TIJ4 Chapter Exceptions, Exercise 6, page 456
/* Create two exception classes, each of which performs its own logging
* automtically. Demonstrate that these work.
*/
import java.util.logging.*;
import java.io.*;
class Oops1 extends Exception {
private static Logger logger = Logger.getLogger("LoggingException");
public Oops1() {
StringWriter trace = new StringWriter();
printStackTrace(new PrintWriter(trace));
logger.severe(trace.toString());
}
}
class Oops2 extends Exception {
private static Logger logger = Logger.getLogger("LoggingException");
public Oops2() {
StringWriter trace = new StringWriter();
printStackTrace(new PrintWriter(trace));
logger.severe(trace.toString());
}
}
public class Ex6 {
static void f() throws Oops1, Oops2 {
throw new Oops1();
}
static void g() throws Oops2 {
throw new Oops2();
}
public static void main(String[] args) {
try {
f();
} catch(Exception Oops1) {}
try {
g();
} catch(Exception Oops2) {}
}
}
// exceptions/Ex7.java
// TIJ4 Chapter Exceptions, Exercise 7, page 456
// Modify Exercise 3 so that the catch clause logs the result.
import java.util.logging.*;
import java.io.*;
public class Ex7 {
private static int[] ia = new int[2];
private static Logger logger = Logger.getLogger("Ex7 Exceptions");
static void logException(Exception e) { // Exception e argument
StringWriter trace = new StringWriter();
e.printStackTrace(new PrintWriter(trace));
logger.severe(trace.toString());
}
public static void main(String[] args) {
try {
ia[2] = 3;
} catch(ArrayIndexOutOfBoundsException e) {
System.err.println(
"Caught ArrayIndexOutOfBoundsException");
e.printStackTrace();
// call logging method:
logException(e);
}
}
}
// exceptions/Ex8.java
// TIJ4 Chapter Exceptions, Exercise 8, page 458
/* 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 Exception4 extends Exception {
private String msg;
Exception4(String msg) {
super(msg);
System.out.println("Exception4()");
this.msg = msg;
}
protected void showS() {
System.out.println("Message from Exception4: " + msg);
}
}
class Test8 {
public static void f() throws Exception4 {
System.out.println("f()");
throw new Exception4("Ouch from f()");
}
}
public class Ex8 {
public static void main(String[] args) {
try {
Test8 t = new Test8();
t.f();
} catch(Exception4 e) {
System.err.println("Caught Exception4");
e.printStackTrace();
e.showS();
}
}
}
// exceptions/Ex9.java
// TIJ4 Chapter Exceptions, Exercise 9, page 460
/* 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.
*/
import static net.mindview.util.Print.*;
class ExceptionA extends Exception {
ExceptionA(String msg) { super(msg); }
}
class ExceptionB extends Exception {
ExceptionB(String msg) { super(msg); }
}
class ExceptionC extends Exception {
ExceptionC(String msg) { super(msg); }
}
public class Ex9 {
public static void f(int x) throws ExceptionA, ExceptionB, ExceptionC {
if(x < 0) throw new ExceptionA("x < 0");
if(x == 0) throw new ExceptionB("x == 0");
if(x > 0) throw new ExceptionC("x > 0");
}
public static void main(String[] args) {
try {
f(0);
f(1);
f(-1);
// will catch any Exception type:
} catch(Exception e) {
print("Caught Exception");
e.printStackTrace(System.out);
}
}
}
// exceptions/Ex10.java
// TIJ4 Chapter Exceptions, Exercise 10, page 468
/* 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().
*/
import static org.greggordon.tools.Print.*;
class GException extends Exception {
GException(String s) { super(s); }
}
class HException extends Exception {
HException(String s) { super(s); }
}
public class Ex10 {
static void f() {
try {
try {
g();
} catch(GException ge) {
println("Caught GException in f inner try");
ge.printStackTrace();
throw new HException("from f(), inner try");
}
} catch(HException he) {
println("Caught HException in f() outer try");
he.printStackTrace(System.out);
}
}
static void g() throws GException {
throw new GException("from g()");
}
public static void main(String[] args) {
f();
}
}
// exceptions/Ex11.java
// TIJ4 Chapter Exceptions, Exercise 11, page 468
/* Repeat the previous exercise, but inside the catch clause, wrap g()'s
* exception in a RuntimeException.
*/
import static org.greggordon.tools.Print.*;
class GException extends Exception {
GException(String s) { super(s); }
}
public class Ex11 {
static void f() {
try {
g();
} catch(GException ge) {
println("Caught GException in f try");
ge.printStackTrace();
throw new RuntimeException(ge);
}
}
static void g() throws GException {
throw new GException("from g()");
}
public static void main(String[] args) {
f();
}
}
// exceptions/Sequence12.java
// TIJ4 Chapter Exceptions, Excercise 12, page 471
/* 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();
}
public class Sequence12 {
private Object[] items;
private int next = 0;
public Sequence12(int size) { items = new Object[size]; }
public void add(Object x) throws ArrayIndexOutOfBoundsException {
// check for full array first:
if(next == items.length)
throw new ArrayIndexOutOfBoundsException();
// if not full, fill:
if(next < items.length)
items[next++] = x;
}
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) {
Sequence12 sequence = new Sequence12(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();
}
System.out.println();
// attempt to add object to full array produces
// ArrayIndexOutOfBoundsException:
sequence.add(Integer.toString(10));
}
}
// exceptions/Ex13.java
// TIJ4 Chapter Exceptions, Exercise 13, page 476
/* Modify Exercise 9 by adding a finally clause. Verify that your
* finally clause is executed, even if a NullPointerException is thrown.
*/
import static net.mindview.util.Print.*;
class ExceptionA extends Exception {
ExceptionA(String msg) { super(msg); }
}
class ExceptionB extends Exception {
ExceptionB(String msg) { super(msg); }
}
class ExceptionC extends Exception {
ExceptionC(String msg) { super(msg); }
}
public class Ex13 {
// array element will be initialized to null:
private static Integer[] x = new Integer[1];
public static void f(int x)
throws ExceptionA, ExceptionB, ExceptionC {
if(x < 0) throw new ExceptionA("x < 0");
if(x == 0) throw new ExceptionB("x == 0");
if(x > 0) throw new ExceptionC("x > 0");
}
public static void main(String[] args) {
try {
// to throw NullPointerException:
f(x[0]);
f(0);
f(1);
f(-1);
// will catch any Exception type:
} catch(Exception e) {
print("Caught Exception");
e.printStackTrace(System.out);
} finally {
print("made it to finally");
}
}
}
// exceptions/OnOffSwitch14.java
// TIJ4 Chapter Exceptions, Exercise 14, page 476
// Show that the OnOffSwitch.java can fail by throwing a
// RuntimeException inside the try block.
public class OnOffSwitch14 {
private static Switch sw = new Switch();
static Integer[] x = new Integer[1];
public static void f(int i)
throws OnOffException1, OnOffException2 {}
public static void main(String[] args) {
try {
sw.on();
// Code that can throw RuntimeException
// and leave Switch on:
f(x[0]);
sw.off();
} catch(OnOffException1 e) {
System.out.println("OnOffException1");
sw.off();
} catch(OnOffException2 e) {
System.out.println("OnOffException2");
sw.off();
}
}
}
// exceptions/WithFinally15.java
// TIJ4 Chapter Exceptions, Exercise 15, page 476
// Show that WithFinally.java doesn't fail by throwing a
// RuntimeException inside the try block.
public class WithFinally15 {
private static Switch sw = new Switch();
// set up x[0] = null:
private static Integer[] x = new Integer[1];
public static void f(int i)
throws OnOffException1, OnOffException2 {}
public static void main(String[] args) {
try {
sw.on();
// Code to throw NullPointerException:
f(x[0]);
} catch(OnOffException1 e) {
System.out.println("OnOffException1");
} catch(OnOffException2 e) {
System.out.println("OnOffException2");
} finally {
sw.off();
}
}
}
// reusing/CADSystem16.java
// TIJ4 Chapter Exceptions, Exercise 16, page 477
// MOdify reusing/CADSystem.java to demonstrate that returning from the
// middle of a try-finally will still perform. proper cleanup.
package exceptions;
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 dipsose() {
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 CADSystem16 extends Shape {
private Circle c;
private Triangle t;
private Line[] lines = new Line[3];
public CADSystem16(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("CADSystem.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) {
CADSystem16 x = new CADSystem16(47);
try {
print("Returning from try block");
return;
// unreachable statement:
// print("You can't see this");
// but finally block will still execute:
} finally {
x.dispose();
}
}
}
// exceptions/Frog17.java
// TIJ4 Chapter Exceptions, Exercise 17, page 477
/* Modify pholymorphism/Frog.java so that it uses try-finally to
* guarantee proper cleanup, and show that this works even if you
* return from the middle of the try-finally.
*/
package exceptions;
import static net.mindview.util.Print.*;
class Characteristic {
private String s;
Characteristic(String s) {
this.s = s;
print("Creating Characteristic " + s);
}
protected void dispose() {
print("disposing Characteristic " + s);
}
}
class Description {
private String s;
Description(String s) {
this.s = s;
print("Creating Description " + s);
}
protected void dispose() {
print("disposing Description " + s);
}
}
class LivingCreature {
private Characteristic p = new Characteristic("is alive");
private Description t = new Description("Basic Living Creature");
LivingCreature() {
print("LivingCreature()");
}
protected void dispose() {
print("LivingCreature dispose");
t.dispose();
p.dispose();
}
}
class Animal extends LivingCreature {
private Characteristic p = new Characteristic("has heart");
private Description t = new Description("Animal not Vegetable");
Animal() { print("Animal()"); }
protected void dispose() {
print("Animal dispose");
t.dispose();
p.dispose();
super.dispose();
}
}
class Amphibian extends Animal {
private Characteristic p = new Characteristic("can live in water");
private Description t = new Description("Both water and land");
Amphibian() { print("Amphibian()"); }
protected void dispose() {
print("Amphibian dispose");
t.dispose();
p.dispose();
super.dispose();
}
}
public class Frog17 extends Amphibian {
private Characteristic p = new Characteristic("Croaks");
private Description t = new Description("Eats Bugs");
public Frog17() { print("Frog17()"); }
public static void jump() { print("frog jumps"); }
protected void dispose() {
print("Frog17 dispose");
t.dispose();
p.dispose();
super.dispose();
}
public static void main(String[] args) {
Frog17 frog = new Frog17();
try {
frog.jump();
print("Returning from try-finally");
return;
} finally {
print("Bye!");
frog.dispose();
}
}
}
// exceptions/LostMessage18.java
// TIJ4 Chapter Exceptions, Exercise 18, page 479
// 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 MeaninglessException extends Exception {
public String toString() {
return "A meaningless exception";
}
}
public class LostMessage18 {
void f() throws VeryImportantException {
throw new VeryImportantException();
}
void dispose() throws HoHumException {
throw new HoHumException();
}
void eliminate() throws MeaninglessException {
throw new MeaninglessException();
}
public static void main(String[] args) {
try {
LostMessage18 lm = new LostMessage18();
try {
try {
lm.f();
lm.dispose();
} finally {
lm.eliminate();
}
} catch(Exception e) {
System.out.println(e);
}
} catch(Exception e) {
System.out.println(e);
}
}
}
// exceptions/LostMessageFound19.java
// TIJ4 Chapter Exceptions, Exercise 19, page 479
// 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 LostMessageFound19 {
void f() throws VeryImportantException {
throw new VeryImportantException();
}
void dispose() throws HoHumException {
throw new HoHumException();
}
public static void main(String[] args) {
try {
LostMessageFound19 lmf = new LostMessageFound19();
try {
lmf.f();
} catch(Exception e) {
System.out.println(e);
} finally {
lmf.dispose();
}
} catch(Exception e) {
System.out.println(e);
}
}
}
// exceptions/StormyInning20.java
// TIJ4 Chapter Exceptions, Exercise 20, page
/* MOdify StormyInning.java by adding an UmpireArgument exception type
* and methods that throw this exception. Test the modified hierarchy.
*/
// Overridden methods may throw only the exceptions
// specified in their base-class versions, or exceptions
// derived from the base-class exceptions.
class BaseballException extends Exception {}
class Foul extends BaseballException {}
class Strike extends BaseballException {}
class UmpireArgument extends BaseballException {}
class ThrownFromGame extends UmpireArgument {}
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, UmpireArgument;
public void questionableCall() throws UmpireArgument {}
public void walk() {} // Throws no checked exceptions
}
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 StormyInning20 extends Inning implements Storm {
// OK to add new exceptions for constructors, but you
// must deal with the base constructor exceptions:
public StormyInning20()
throws UmpireArgument, RainedOut, BaseballException {}
public StormyInning20(String s)
throws Foul, BaseballException {}
// Regular methods must comform. 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 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 class version does:
public void event() {}
// Overridden methods can throw inherited exceptions:
public void atBat() throws PopFoul, ThrownFromGame {
throw new ThrownFromGame();
}
public void questionableCall() throws UmpireArgument {
throw new UmpireArgument();
}
public static void main(String[] args) {
try {
StormyInning20 si = new StormyInning20();
si.atBat();
si.questionableCall();
} catch(PopFoul e) {
System.out.println("Pop foul");
} catch(UmpireArgument e) {
System.out.println("Umpire argument (StormyInning20)");
// } catch(ThrownFromGame e) {
// System.out.println("Thrown from game");
} 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 StormyInning20();
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(ThrownFromGame e) {
System.out.println("Thrown from game (Inning)");
} catch(RainedOut e) {
System.out.println("Rained out");
} catch(BaseballException e) {
System.out.println("Generic baseball exception");
}
}
}
// exceptions/Ex21.java
// TIJ4 Chapter Exceptions, Exercise 21, page 488
// Demonstrate that a derived-class constructor cannot catch exceptions thrown
// by its base-class constructor.
class BaseException extends Exception {}
class Base {
Base() throws BaseException {
throw new BaseException();
}
}
class Derived extends Base {
// BaseException must be caught (no way) or
// declared to be thrown:
Derived() throws BaseException {
super();
// not this way, 'catch' without 'try' not allowed:
// catch(BaseException e) {}
// not this way either, because call to super
// must be first statement in constructor:
// try {
// super();
// } catch(BaseException e) {}
}
}
public class Ex21 {
public static void main(String[] args) {
try {
Derived d = new Derived();
} catch(BaseException e) {
System.out.println("BaseException caught in main()");
}
}
}
// exceptions/FailingConstructor22.java
// TIJ4 Chapter Exceptions, Exercise 22, page 488
/* 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.
*/
public class FailingConstructor22 {
Integer[] ia = new Integer[2];
String s;
FailingConstructor22(String s) throws Exception {
ia[0] = 0;
ia[1] = 1;
ia[2] = 2;
this.s = s;
}
public static void main(String[] args) {
try {
FailingConstructor22 fc = new FailingConstructor22("hi");
} catch(Exception e) {
System.err.println("Caught Exception in main()");
e.printStackTrace(System.err);
} finally {
}
}
}
// exceptions/FailingConstructor22b.java
// TIJ4 Chapter Exceptions, Exercise 22 page 488
/* 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.
*/
// Solution modeled from examples in text:
import java.io.*;
public class FailingConstructor22b {
private BufferedReader in;
public FailingConstructor22b(String fname) throws Exception {
try {
in = new BufferedReader(new FileReader(fname));
} catch(FileNotFoundException e) {
System.out.println("Could not find file " + fname);
throw e;
} catch(Exception e) {
try {
in.close();
} catch(IOException e2) {
System.out.println("in.close() failed");
}
throw e;
}
}
public String getLine() {
String s;
try {
s = in.readLine();
} catch(IOException e) {
throw new RuntimeException("readLine() failed");
}
return s;
}
public static void main(String[] args) {
try {
FailingConstructor22b fc =
new FailingConstructor22b("AlwaysFinally.java");
try {
String s;
int i = 1;
while((s = fc.getLine()) != null) {
// code to print to new file:
// println(i + " " + s);
// i++;
}
} catch(Exception e) {
System.out.println("Exception caught in main()");
e.printStackTrace(System.err);
}
} catch(Exception e) {
System.out.println("FailingConstructor22b construction failed");
}
}
}
// exceptions/FailingConstructor23.java
// TIJ4 Chapter Exceptions, Exercise 23, page 489
/* Add a class with a dispose() method to the previous exercise. Modify
* FailingConstructor so that the constructor creates one of these disposable
* objects, after which the constructor might through an exception, after which
* it creates a second disposable member object. Write code to properly guard
* against failure, and in main() verify that all possible failure situations
* are covered.
*/
// This solution satisfies the conditions called for in FailingConstructor23
// constructor, which catches its own exceptions.
import static org.greggordon.tools.Print.*;
class Disposable {
private static int counter = 0;
private int id = counter++;
private boolean disposed;
Disposable() {
disposed = false;
}
void dispose() {
disposed = true;
}
String checkStatus() {
return (id + " " + (disposed ? "disposed" : "not disposed"));
}
}
public class FailingConstructor23 {
private Integer[] ia = new Integer[2];
private static Disposable d0;
private static Disposable d1;
FailingConstructor23() throws Exception {
try {
d0 = new Disposable();
try {
ia[2] = 2; // causes exception thrown and
// caught in middle try loop
try {
d1 = new Disposable();
} catch(Exception e) {
println("Caught e in inner try loop");
e.printStackTrace(System.err);
println("Failed to create d1");
}
} catch(Exception e) {
println("Caught e in middle try loop");
e.printStackTrace(System.err);
println("Disposing d0");
d0.dispose(); // d0 would have been created
}
} catch(Exception e) {
println("Caught e in outer try loop");
e.printStackTrace(System.err);
println("Failed to create d0");
}
}
public static void main(String[] args) {
try {
// the constructor catches its own exceptions:
FailingConstructor23 fc = new FailingConstructor23();
} catch(Exception e) {
System.err.println("Caught Exception in main()");
e.printStackTrace(System.err);
}
}
}
// exceptions/FailingConstructor23b.java
// TIJ4 Chapter Exceptions, Exercise 23, page 489
/* Add a class with a dispose() method to the previous exercise. Modify
* FailingConstructor so that the constructor creates one of these disposable objects
* as a member object, after which the constructor might throw and exception, after
* which it creates a second disposable member object. Write code to properly guard
* against failure, and in main() verify that all possible failure situations are covered.
*/
import static org.greggordon.tools.Print.*;
import java.io.*;
class NeedsCleanup {
private static long counter = 1;
private final long id = counter++;
public void dispose() {
System.out.println("NeedsCleanup " + id + " disposed");
}
}
public class FailingConstructor23b {
private BufferedReader in;
NeedsCleanup nc1;
NeedsCleanup nc2;
public FailingConstructor23b(String fname) throws Exception {
nc1 = new NeedsCleanup();
try {
in = new BufferedReader(new FileReader(fname));
} catch(FileNotFoundException e) {
System.out.println("Could not find file " + fname);
throw e;
} catch(Exception e) {
try {
in.close();
} catch(IOException e2) {
System.out.println("in.close() failed");
}
throw e;
}
nc2 = new NeedsCleanup();
}
public String getLine() {
String s;
try {
s = in.readLine();
} catch(IOException e) {
throw new RuntimeException("readLine() failed");
}
return s;
}
public static void main(String[] args) {
try {
FailingConstructor23b fc =
new FailingConstructor23b("AlwaysFinally.java");
try {
String s;
int i = 1;
while((s = fc.getLine()) != null) {
// code to print to new file:
// println(i + " " + s);
// i++;
}
} catch(Exception e) {
System.out.println("Exception caught in main()");
e.printStackTrace(System.err);
} finally {
fc.nc1.dispose();
fc.nc2.dispose();
}
} catch(Exception e) {
System.out.println("FailingConstructor23b construction failed");
}
}
}
// exceptions/FailingConstructor24b.java
// TIJ4 Chapter Exceptions, Exercise 24 page 489
/* Add a dipsose() method to the FailingConstructor class and write code to properly use
* this class.
*/
// Solution modeled from examples in text:
import java.io.*;
public class FailingConstructor24b {
private BufferedReader in;
public FailingConstructor24b(String fname) throws Exception {
try {
in = new BufferedReader(new FileReader(fname));
} catch(FileNotFoundException e) {
System.out.println("Could not find file " + fname);
throw e;
} catch(Exception e) {
try {
in.close();
} catch(IOException e2) {
System.out.println("in.close() failed");
}
throw e;
}
}
public String getLine() {
String s;
try {
s = in.readLine();
} catch(IOException e) {
throw new RuntimeException("readLine() failed");
}
return s;
}
public void dispose() {
try {
in.close();
System.out.println("dispose() successful");
} catch(IOException e2) {
throw new RuntimeException("in.close() failed");
}
}
public static void main(String[] args) {
try {
FailingConstructor24b fc =
new FailingConstructor24b("AlwaysFinally.java");
try {
String s;
int i = 1;
while((s = fc.getLine()) != null) {
// code to print to new file:
// println(i + " " + s);
// i++;
}
} catch(Exception e) {
System.out.println("Exception caught in main()");
e.printStackTrace(System.err);
} finally {
fc.dispose();
}
} catch(Exception e) {
System.out.println("FailingConstructor22b construction failed");
}
}
}
// exceptions/Ex25.java
// TIJ4 Chapter Exceptions, Exercise 25, page 490
/* 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 LevelOneException extends Exception {}
class LevelTwoException extends LevelOneException {}
class LevelThreeException extends LevelTwoException {}
class A {
void f() throws LevelOneException {
throw new LevelOneException();
}
}
class B extends A {
void f() throws LevelTwoException {
throw new LevelTwoException();
}
}
class C extends B {
void f() throws LevelThreeException {
throw new LevelThreeException();
}
}
public class Ex25 {
public static void main(String[] args) {
A a = new C();
try {
a.f();
} catch(LevelThreeException e3) {
System.out.println("Caught e3");
} catch(LevelTwoException e2) {
System.out.println("Caught e2");
} catch(LevelOneException e1) {
System.out.println("Caught e1");
}
}
}
// exceptions/MainException26.java
import java.io.*;
public class MainException26 {
// Pass all exceptions to the console:
public static void main(String[] args) throws Exception {
// Leads to FileNotFoundException:
FileInputStream file =
new FileInputStream("null.jv");
// Use the file ...
// Close the file:
file.close();
}
}
// exceptions.Ex27.java
// TIJ4 Chapter Exceptions, Exercise 27, page 500
// Modify Exercise 3 to convert the exception to a Runtime Exception.
public class Ex27 {
private static int[] ia = new int[2];
public static void main(String[] args) {
try {
ia[2] = 3;
} catch(ArrayIndexOutOfBoundsException e) { // convert to RuntimeException:
throw new RuntimeException(e);
}
}
}
// exceptions/Ex28.java
// TIJ4 Chapter Exceptions, Exercise 28, page 500
/* 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.
*/
class Exception28 extends RuntimeException {
private String msg;
Exception28(String msg) {
super(msg);
System.out.println("Exception28()");
this.msg = msg;
}
protected void showS() {
System.out.println("Message from Exception4: " + msg);
}
}
public class Ex28 {
public static void f() throws Exception28 {
System.out.println("f()");
throw new Exception28("Ouch from f()");
}
public static void main(String[] args) {
f();
}
}
// exceptions/StormyInning29.java
// TIJ4 Chapter Exceptions, Exercise 29, page 500
/* Modify all the exception types in StormyInning.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 RuntimeException {}
class Strike extends RuntimeException {}
abstract class Inning {
public Inning() {}
public void event() {}
public abstract void atBat();
public void walk() {}
}
class StormException extends RuntimeException {}
class RainedOut extends RuntimeException {}
class PopFoul extends RuntimeException {}
interface Storm {
public void event();
public void rainHard();
}
public class StormyInning29 extends Inning implements Storm {
public StormyInning29() {}
public StormyInning29(String s) {}
public void walk() {}
public void event() {}
public void rainHard() {}
public void atBat() {}
public static void main(String[] args) {
StormyInning29 si = new StormyInning29();
si.atBat();
// What happens if you upcast?
Inning i = new StormyInning29();
i.atBat();
}
}
// exceptions/Human30.java
// TIJ4 Chapter Exceptions, Exercise 30, page 500
/* Modify Human.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 static net.mindview.util.Print.*;
class Annoyance extends RuntimeException {}
class Sneeze extends Annoyance {}
class WrapCheckedExceptions {
void throwRuntimeException(int type) {
try {
switch(type) {
case(0):
throw new Annoyance();
case(1):
throw new Sneeze();
case(2):
throw new RuntimeException("Where am I?");
default: return;
}
} catch(Exception e) {
// Adapt to unchecked:
throw new RuntimeException(e);
}
}
}
public class Human30 {
public static void main(String[] args) {
WrapCheckedExceptions wce =
new WrapCheckedExceptions();
for(int i = 0; i < 3; i++)
try {
if(i < 3)
wce.throwRuntimeException(i);
else
throw new RuntimeException();
} catch(RuntimeException re) {
try {
throw re.getCause();
} catch(Sneeze e) {
print("Sneeze: " + e);
} catch(Annoyance e) {
print("Annoyance: " + e);
} catch(Throwable e) {
print("Throwable: " + e);
}
}
}
}