title: Check generic type before casting at runtime
body: <p>We were given the task to create an object structure for evaluating expressions (e.g. "1 + 2" or "true &amp; false"). The parser is provided, as well as a factory interface to create the expression objects.</p>
  
  <p>We use generics for the different expressions: <code>Expression&lt;Integer&gt;</code> returns an Integer, <code>Expression&lt;Boolean&gt;</code> returns a Boolean, etc.</p>
  
  <p>The problem we're facing is that the provided interface uses the raw type <code>Expression</code>, for example:</p>
  
  <pre><code>public Expression createSumExpression(Expression left, Expression right);
  </code></pre>
  
  <p>The sum expression is only defined when the operands are of type <code>Expression&lt;Integer&gt;</code> or <code>Expression&lt;Double&gt;</code>. How can we check this? 
  Due to type erasure, the type information is not available at run time, and it just results in a <code>ClassCastException</code> if it's incorrect.</p>
  
  <p>I can modify everything, except for the <code>createSumExpression</code> and <code>createAndExpression</code> functions.</p>
  
  <hr>
  
  <p>This is a simplified piece of code that demonstrates the problem. It works, but it doesn't look very nice, and it gives multiple warnings.</p>
  
  <h3>Main.java</h3>
  
  <pre><code>public class Main {
  
      public static void main(String[] args) {
          Expression&lt;?&gt; left1 = new BasicExpression&lt;&gt;(42);
          Expression&lt;?&gt; right1 = new BasicExpression&lt;&gt;(3);        
          Expression&lt;?&gt; sum = createSumExpression(left1, right1);
          System.out.printf("%d + %d = %d%n",left1.getValue(), right1.getValue(), sum.getValue());
  
          Expression&lt;?&gt; left2 = new BasicExpression&lt;&gt;(true);
          Expression&lt;?&gt; right2 = new BasicExpression&lt;&gt;(false);
          Expression&lt;?&gt; and = createAndExpression(left2, right2);
          System.out.printf("%b &amp; %b = %b%n",left2.getValue(), right2.getValue(), and.getValue());
      }
  
      private static Expression createSumExpression(Expression left, Expression right) { // Raw types because of given interface
          return new BinaryExpression&lt;Integer,Expression&lt;Integer&gt;,Expression&lt;Integer&gt;&gt;(left, right) {
              @Override
              protected Integer operation(Expression&lt;Integer&gt; left, Expression&lt;Integer&gt; right) {
                  return left.getValue() + right.getValue();
              }
          };
      }
  
      private static Expression createAndExpression(Expression left, Expression right) { // Raw types because of given interface
          return new BinaryExpression&lt;Boolean,Expression&lt;Boolean&gt;,Expression&lt;Boolean&gt;&gt;(left, right) {
              @Override
              protected Boolean operation(Expression&lt;Boolean&gt; left, Expression&lt;Boolean&gt; right) {
                  return left.getValue() &amp; right.getValue();
              }
          };
      }
  
  }
  </code></pre>
  
  <h3>Expression.java</h3>
  
  <pre><code>abstract public class Expression&lt;V&gt; {
      public abstract V getValue();
  }
  </code></pre>
  
  <h3>BasicExpression.java</h3>
  
  <pre><code>public class BasicExpression&lt;V&gt; extends Expression&lt;V&gt; {
      public BasicExpression(V value) {
          this.value = value; 
      }
      @Override
      public V getValue() {
          return value;
      }
      private V value;
  }
  </code></pre>
  
  <h3>BinaryExpression.java</h3>
  
  <pre><code>abstract public class BinaryExpression&lt;V, L, R&gt; extends Expression&lt;V&gt; {
      public BinaryExpression (L l, R r) {
          this.left = l;
          this.right = r;
      }
      @Override
      public V getValue() {
          return operation(left, right);
      }
      abstract protected V operation(L left, R right);
  
      private L left;
      private R right;
  }
  </code></pre>
  
  <hr>
  
  <p>The provided interface is:</p>
  
  <pre><code>/**
   * @param &lt;E&gt;
   *            Your class for representing an expression.
   */
  public interface IExpressionFactory&lt;E&gt; {
      public E createSumExpression(E left, E right) throws ModelException;
      public E createAndExpression(E left, E right) throws ModelException;
      // ...
  }
  </code></pre>