title: Restrictions on Java intersection types with interfaces classes and type variables
body: <p>Today I tried to write a class with a generic method that uses intersection types and got confused by the different error messages depending on the intersected types. Let's assume that we have an <code>interface</code> and a <code>class</code> and define generic methods in a generic interface:</p>
  
  <pre><code>class ClassType {
  }
  
  interface InterfaceType {
  }
  
  interface I&lt;T&gt; {
      public &lt;X extends InterfaceType &amp; InterfaceType&gt; void foo();
  
      public &lt;X extends ClassType &amp; ClassType&gt; void foo1();
  
      public &lt;X extends ClassType &amp; InterfaceType&gt; void foo2();
  
      public &lt;X extends InterfaceType &amp; ClassType&gt; void foo3();
  
      public &lt;X extends T &amp; ClassType&gt; void foo4();
  
      public &lt;X extends ClassType &amp; T&gt; void foo5();
  
      public &lt;X extends InterfaceType &amp; T&gt; void foo6();
  
      public &lt;X extends T &amp; InterfaceType&gt; void foo7();
  }
  </code></pre>
  
  <p>Compiling this produces errors for all method except for <code>public &lt;X extends ClassType &amp; InterfaceType&gt; void foo2();</code>.</p>
  
  <pre><code>Main.java:8: error: repeated interface
      public &lt;X extends InterfaceType &amp; InterfaceType&gt; void foo();
                                        ^
  Main.java:10: error: interface expected here
      public &lt;X extends ClassType &amp; ClassType&gt; void foo1();
                                    ^
  Main.java:14: error: interface expected here
      public &lt;X extends InterfaceType &amp; ClassType&gt; void foo3();
                                        ^
  Main.java:16: error: a type variable may not be followed by other bounds
      public &lt;X extends T &amp; ClassType&gt; void foo4();
                            ^
  Main.java:18: error: unexpected type
      public &lt;X extends ClassType &amp; T&gt; void foo5();
                                    ^
    required: class
    found:    type parameter T
    where T is a type-variable:
      T extends Object declared in interface I
  Main.java:20: error: unexpected type
      public &lt;X extends InterfaceType &amp; T&gt; void foo6();
                                        ^
    required: class
    found:    type parameter T
    where T is a type-variable:
      T extends Object declared in interface I
  Main.java:22: error: a type variable may not be followed by other bounds
      public &lt;X extends T &amp; InterfaceType&gt; void foo7();
                            ^
  7 errors
  </code></pre>
  
  <p>Since intersection should be symmetric, I am surprised that <code>foo2</code> is accepted but <code>foo3</code> is rejected. Why is this one case accepted?</p>
  
  <p>I am also wondering in general why there is a distinction between interfaces, classes and type parameters when it comes to intersection types. I can see reasons to not allow more than one class in an intersection type, but the current state accepting <code>ClassType &amp; InterfaceType</code> but not <code>InterfaceType &amp; ClassType</code> seems strangely arbitrary. An intersection <code>A &amp; A</code> is also forbidden, but this is semantically identical to <code>A</code> so I don't see a reason for this.</p>
  
  <p>I am also curious why type variables are not allowed in the intersection. Worst case would be an intersection of two or more classes, but would just be an uninhabited type, so the bottom type.</p>