Class NonLocalExit

java.lang.Object
  extended by NonLocalExit

public class NonLocalExit
extends java.lang.Object


Nested Class Summary
static class NonLocalExit.Jump
          The main reason this is public is to allow clients of NonLocalExit to write catches on it.
 
Field Summary
protected  NonLocalExit.Jump jump
          The most recent exception created to throw at me is stored here.
protected  java.lang.Thread scope
          Accessibility is limited to the current thread, and (when I go out of scope) is set to null to indicate no access.
 
Constructor Summary
NonLocalExit()
          Create a non-local exit point at the start of some scope.
 
Method Summary
 void close()
          Make me go out of scope.
 void jump()
          Make a non-local jump to the end of my scope.
protected  NonLocalExit.Jump makeJump()
          This is called by jump() to create the throwable which my scope will catch.
 boolean matches(java.lang.Throwable t)
          Must be used in my associated catch clause to verify that a passing exception is one this pertains to me.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

scope

protected java.lang.Thread scope
Accessibility is limited to the current thread, and (when I go out of scope) is set to null to indicate no access.


jump

protected NonLocalExit.Jump jump
The most recent exception created to throw at me is stored here. It is used to distinguish that jump from other jumps to similar scopes. It starts out a null. I can be jumped to any number of times, but only one jump will succeed.

Constructor Detail

NonLocalExit

public NonLocalExit()
Create a non-local exit point at the start of some scope. Caller is responsible to catch, within the scope, Jumps which may be directed at this point, and to close the exit point when it goes out of scope.

Example code:

  NonLocalExit exit = new NonLocalExit();
  try {
      callSomethingRecursiveWithAnEscapeHatch(exit);
      return somethingLocal;
  } catch (NonLocalExit.Jump t) {
      if (!exit.matches(t))
          // These are not the droids you're looking for.  Move along.
          throw t;
      return somethingElseLocal;
  } finally {
      exit.close();
  }
 

Note that this class can be subclassed to “box” a return value, which would be delivered instead of somethingElseLocal in the above example.

Method Detail

makeJump

protected NonLocalExit.Jump makeJump()
This is called by jump() to create the throwable which my scope will catch. An ingenious client might override this so as to use a sharper exception type when there are overlapping and independent non-local returns in a program. This is not the common case, though. The ingenious client should consider using clone of a pre-allocated subclass instance, in order to avoid the high cost of Throwable.fillInStackTrace.


jump

public void jump()
Make a non-local jump to the end of my scope. Concretely, throw an exception to my associated exception handler which matches me. This is usually invoked at most once per exit point instance.


matches

public boolean matches(java.lang.Throwable t)
Must be used in my associated catch clause to verify that a passing exception is one this pertains to me. If it returns true, then the caller should pass control normally out of my associated scope. If it returns false, the the caller must rethrow the caught exception, because it is aimed at a different scope (i.e., a different NonLocalExit instance).


close

public void close()
Make me go out of scope. Caller should do this in a finally clause, or else error checking may produce unhelpful results.