javaeclipsename-clash

Java - 'Name clash' and 'constructor undefined' error when overriding inner class that inherits a generic from the outer class


I recently upgraded the eclipse and java version in a project and some errors occured. I tried to reproduce and found out that the following setup lead to the errors in in Eclipse Oxigen.3a (4.7.3a) using Java 1.8, while the same works with eclipse 3.7.2 and Java 1.7

TestSomeObject.java:

package a;
public class TestSomeObject
{
}

TestGeneric.java:

package a;
public class TestGeneric<T>
{
  T element;

  protected class InnerGeneric
  {
     T innerElement;

     public InnerGeneric() { }
  }
}

TestA.java:

package a;

public class TestA extends TestGeneric<TestSomeObject>
{
  public TestA(String a, String b) {}

  public InnerA someMethod(String some, InnerGeneric inner)
  {
     return new InnerA(some, inner);
  }

  protected class InnerA
  {
     public InnerA(String a, InnerGeneric b) {  }
  }
}

TestB.java

package a;
import a.TestA;

public class TestB extends TestA
{
  public TestB(String a, String b){
     super(a,b);
  }

  public InnerA someMethod(String some, InnerGeneric inner)
  {
     return new InnerB(some, inner);
  }

  protected class InnerB extends InnerA
  {
     public InnerB(String a, InnerGeneric b)
     {
        super(a, b);
     }
  }
}

In class Test B, I get the following compilation errors:

  1. someMethod: Description Resource Path Location Type Name clash: The method someMethod(String, TestGeneric<TestSomeObject>.InnerGeneric) of type TestB has the same erasure as someMethod(String, TestGeneric<TestSomeObject>.InnerGeneric) of type TestA but does not override it TestB.java line 13 Java Problem
  2. when calling super(a,b): Description Resource Path Location Type The constructor TestA.InnerA(String, TestGeneric<TestSomeObject>.InnerGeneric) is undefined TestB.java line 22enter code hereJava Problem

In eclipse Version: 3.7.2 and Java 1.7, this works.

Why is that? What can I do to clear the errors?


Solution

  • The answer is, to more precisely define the InnerGeneric class in the method signature:

    TestB.java:

    package a;
    
    public class TestB extends TestA
    {
      public TestB(String a, String b){
         super(a,b);
      }
    
      public InnerA someMethod(String some, TestGeneric<TestSomeObject>.InnerGeneric inner)
      {
         return new InnerB(some, inner);
      }
    
      protected class InnerB extends InnerA
      {
         public InnerB(String a, TestGeneric<TestSomeObject>.InnerGeneric b)
         {
            super(a, b);
         }
      }
    }