错误的类型推断

时间:2013-01-27 23:07:47

标签: java eclipse generics

我有以下代码:

SomeInterface self = sessionContext.getBusinessObject(sessionContext.getInvokedBusinessInterface());

以下方法签名(来自eclipse工具提示的(非真实代码)):

<Object> Object javax.ejb.SessionContext.getBusinessObject(Class<Object> arg0) throws IllegalStateException

由于某种原因,返回类型被解析为Object。这很奇怪,因为eclipse并没有将这一行标记为错误,但是ant和maven构建器在此行上失败,说Object不能转换为SomeInterface。

我有几个问题:

  • 我的代码有什么问题,所以类型推断不正确(实际上它不应该是Object作为变量类型是SomeInterface)?
  • 为什么line在eclipse(bug)中没有被标记为错误?

我有以下示例,它在eclipse下正确编译,但在maven中失败:

public class TestClass implements SomeInterface {
    private Resolver resolver;

    /**
     * 
     */
    @SuppressWarnings("unchecked")
    public TestClass() {
        SomeInterface c = resolver.some(resolver.someClass());
    }

    @Override
    public void something() {
    }
}

class Resolver {
    public <T> T some(final Class<T> c) {
        return null;
    }

    public Class someClass() {
        return null;
    }
}

interface SomeInterface {
    void something();
}

这里的类型是正确推断的(来自eclipse工具提示(不是真正的代码)):

 <SomeInterface> SomeInterface Resolver.some(Class<SomeInterface> c)

但是这个类仍然无法用maven编译器编译。

我正在使用eclipse juno。

UPD

Maven失败:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.2:compile (default-compile) on project jpharm-server: Compilation failure
[ERROR] TestClass.java:[21,39] incompatible types
[ERROR] found   : java.lang.Object
[ERROR] required: SomeInterface

2 个答案:

答案 0 :(得分:4)

你可以写:

SomeInterface c = resolver.<SomeInterface> some(resolver.someClass());

帮助编译器。

您提供的具体示例不应编译。在应用类型推断时,编译器会尝试查找适合该语句的所有操作数的最具体类型。在这里,resolver.someClass()会返回Class,这可能是任何类,即它真的是Class<? extends Object>,并且无法推断? extends ObjectSomeInterface

例如,someClass可能是:

public Class someClass() {
    return Object.class;
}

答案 1 :(得分:1)

问题在于这一行:

public Class someClass() {

这将返回一个原始类型Class对象,该对象几乎等同于Class<? extends Object>。您应该将此方法设为通用:

public Class<? extends T> someClass() {

并将其命名为:

resolver.<SomeInterface>someClass();

理想情况下,您需要在getInvokedBusinessInterface()的签名中填写实际类型,以便返回Class<? extends SomeInterface>