为什么Java不允许在通用方法定义中使用包?

时间:2018-01-30 03:35:14

标签: java generics openjdk

问题:

在尝试定义Generic方法时,Java似乎存在构建问题,如下所示:

public <otherPackage.TypeA, otherPackage.TypeB> 
    void someMethod (otherPackage.TypeA a, otherPackage.TypeB b)

由于名称项目要求,我有几个具有相同名称的类。特别是,在我的实现中,我在名为myPackage的名称空间Thing中有一个类,它有一个带参数otherPackageOne.ThingotherPackageTwo.Thing的方法。我试图编写一个模板化的方法来利用类型推断,而不是在我使用接口时必须明确指定类型。

问题:

很简单,为什么Java在Generic中包含包有问题?我的研究没有找到任何明显的迹象表明为什么不允许Method Generics包含包路径。我希望在这里提出这个问题可以提供有关为什么会出现这种情况的见解。

注意:

作为一个快速说明,我已经计划重新设计代码,以便我有一个模板化的接口而不是模板化的方法。在通用定义中包含Package时,似乎模板化接口没有问题。我只是希望能够理解为什么Java对我之前编写代码的方式存在问题。

以下是我的代码示例:

Class TypeA

package otherPackage;
public class TypeA { /* Do Nothing */ }

Class TypeB

package otherPackage;
public class TypeB { /* Do Nothing */ }

接口SomeInterface

package genericsTest;   
public interface SomeInterface {
    <U, T> void someMethod (U u, T t);
}

Class SomeClassOne

// This works
package genericsTest;
import otherPackage.TypeA;
import otherPackage.TypeB;
public class SomeClassOne implements SomeInterface 
{
    @Override
    public <TypeA, TypeB> void someMethod (TypeA a, TypeB b) 
    {
        // Do Nothing
    }
}

Class SomeClassTwo

// This doesn't seem to work
package genericsTest;
public class SomeClassTwo implements SomeInterface 
{
    @Override
    public <otherPackage.TypeA, otherPackage.TypeB> 
        void someMethod (otherPackage.TypeA a, otherPackage.TypeB b) 
    {
        // Do Nothing
    }
}

如果它有帮助/重要,我正在使用Intellij和OpenJDK 1.8.0_131。

1 个答案:

答案 0 :(得分:3)

public <TypeA, TypeB> void someMethod (TypeA a, TypeB b)指定&#34;名称&#34; /&#34;占位符&#34;泛型类型(不是它的实际约束),因此otherPackage.TypeA是无效的&#34;名称&#34;通用类型。相反,它需要更像......

public <TA extends otherPackage.TypeA, TB extends otherPackage.TypeB> void someMethod (TA a, TB b) {...}

取决于您尝试实现的目标。

...虽然

public void someMethod (otherPackage.TypeA a, otherPackage.TypeB b) {...}

等同于同一件事,因此会引发更多问题

  

您建议的两个选项都为我提供了以下错误:&#34; Method不会覆盖其超类&#34;中的方法。我忘记在原始提交中包含@Overrides。为了清楚起见,已添加它们。

抱歉,错过了interface

您需要在interface中定义约束,或者类似......

public interface SomeInterface {
    public <U extends otherPackage.TypeA, T extends otherPackage.TypeB> void someMethod(U u, T t);
}

然后允许你做...

public class SomeClassOne implements SomeInterface {

    @Override
    public <U extends otherPackage.TypeA, T extends otherPackage.TypeB> void someMethod(U u, T t) {
    }

}

或者,我怀疑你想......

public interface SomeInterface<U, T> {
    public void someMethod(U u, T t);
}

这将允许你做...

public class SomeClassOne implements SomeInterface<otherPackage.TypeA, otherPackage.TypeB> {

    @Override
    public void someMethod(TypeA u, TypeB t) {
    }

}