title: java - Return a value from Visitor
body: <p>Suppose we have following classes which we can't change:</p>
  
  <pre><code>interface Base {
      void accept(Visitor visitor);
  }
  
  class Foo implements Base {
      short getShortValue() {
          return 1;
      }
  
      @Override
      public void accept(Visitor visitor) {
          visitor.visit(this);
      }
  }
  
  class Bar implements Base {
      int getIntValue() {
          return 2;
      }
  
      @Override
      public void accept(Visitor visitor) {
          visitor.visit(this);
      }
  }
  
  interface Visitor {
      void visit(Foo foo);
  
      void visit(Bar bar);
  }
  </code></pre>
  
  <p>And we need to implement method:</p>
  
  <pre><code> int getValue(Base base)
  </code></pre>
  
  <p>There are many possibilities to do it with visitor using some storage object:</p>
  
  <pre><code>int useArray(Base base) {
      int[] result = new int[1];
  
      base.accept(new Visitor() {
          @Override
          public void visit(Foo foo) {
              result[0] = foo.getShortValue();
          }
  
          @Override
          public void visit(Bar bar) {
              result[0] = bar.getIntValue();
          }
      });
  
      return result[0];
  }
  
  int useAtomic(Base base) {
      AtomicInteger result = new AtomicInteger();
  
      base.accept(new Visitor() {
          @Override
          public void visit(Foo foo) {
              result.set(foo.getShortValue());
          }
  
          @Override
          public void visit(Bar bar) {
              result.set(bar.getIntValue());
          }
      });
  
      return result.intValue();
  }
  
  int useMutable(Base base) {
      MutableInteger result = new MutableInteger(0);
  
      base.accept(new Visitor() {
          @Override
          public void visit(Foo foo) {
              result.setValue(foo.getShortValue());
          }
  
          @Override
          public void visit(Bar bar) {
              result.setValue(bar.getIntValue());
          }
      });
  
      return result.getValue();
  }
  </code></pre>
  
  <p>Or something perverted:</p>
  
  <pre><code>int useException(Base base) {
      class GotResult extends RuntimeException {
          private final int value;
  
          public GotResult(int value) {
              this.value = value;
          }
      }
  
      try {
          base.accept(new Visitor() {
              @Override
              public void visit(Foo foo) {
                  throw new GotResult(foo.getShortValue());
              }
  
              @Override
              public void visit(Bar bar) {
                  throw new GotResult(bar.getIntValue());
              }
          });
      } catch (GotResult result) {
          return result.value;
      }
  
      throw new IllegalStateException();
  }
  </code></pre>
  
  <p>Or don't use visitor at all:</p>
  
  <pre><code>int useCast(Base base) {
      if (base instanceof Foo) {
          return ((Foo) base).getShortValue();
      }
      if (base instanceof Bar) {
          return ((Bar) base).getIntValue();
      }
      throw new IllegalStateException();
  }
  </code></pre>
  
  <p>Are these our only options now? We have Java 8 (will have 9 soon enough) and still writing these ugly pieces of error-prone code. :)</p>