Java从方法返回类型派生的泛型类型推断

ebe*_*ger 5 java generics type-inference javac eclipse-jdt

public class TestCase {
    public static String compiles() {
        return getAction();
    }

    /*
    public static String doesntCompile1() {
        return (String) getAction();
    }

    public static String doesntCompile2() {
        return TestCase.<String> getAction();
    }
    */

    public static <T extends javax.swing.Action> T getAction() {
        return (T) null;
    }
}
Run Code Online (Sandbox Code Playgroud)

这应该被视为javac v1.6.0_22和jdt v3.7.1中的错误吗?对我来说似乎是这样,因为在其他情况下,编译器实际上发现了潜在的ClassCastException.在compiles方法中,这将在运行时抛出ClassCastException.

带来这个例子的原始代码没有在javac中编译,打印出以下异常.不幸的是,我出于某种原因提供的例程代码不会产生此错误.

type parameters of <T>T cannot be determined;
no unique maximal instance exists for type variable T with upper bounds
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 3

我希望一个好的编译器能够检测到错误,但作为一种优化。您提出了一个更一般案例的具体案例,如下所示:

public class TestCase {
    public static TypeA methodA() {
        return methodB();
    }

    public static <T extends TypeB> T methodB() {
        return (T) null;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,总的来说,这没有什么问题,只要:

  1. 如果 TypeA 和 TypeB 都是类,则 TypeB 是 TypeA 的超类。
  2. TypeA或 TypeA 的子类型之一继承自 TypeB。

现在编译器没有检查的关键是#2,在这种情况下它可以检查。但这只是因为这String是最后一堂课。如果该类不是最终类,#2 将始终为真,因为潜在的子类在编译时未知。

想象一下String,您使用了CharSequence. 然后我希望所有三个都能编译。但是,我无法解释为什么在您的示例中第二个和第三个方法无法编译。

编辑

现在我已经尝试过javac,发现第一种方法也无法编译。上面接受了你问题的前提,这似乎是错误的。我收到误导性的编译错误

不兼容的类型。必需的:java.lang.String。成立:T

这个答案并没有回答完整的问题,而是解释了为什么它不起作用,但如下所示:

public static CharSequence compiles() {
    return (CharSequence)getAction();
}
Run Code Online (Sandbox Code Playgroud)

做。