使java编译器输出类型推断信息

Joe*_*ney 8 java generics type-inference javac

是否有可能获得javac有关它为方法调用推断的类型的输出信息?

例如,我想知道T调用时推断出正式类型是什么bar.

private static <T> void bar() { ... }
public void foo() {
  bar();
}
Run Code Online (Sandbox Code Playgroud)

我正在探索javac -Xprint和朋友,但找不到任何暴露这种细节水平的东西.


编辑示例.我最初不想这么说,因为它会使答案复杂化.我主要是想从中获取调试信息javac.无论如何,这是激励的例子:

public class Scratch {
  private static <T extends Throwable> void sneakyThrow(Throwable t) throws T {
    throw (T) t; // Warning: Type safety: Unchecked cast from Throwable to T
  }
  public void foo() {
    sneakyThrow(new Exception());
  }
}
Run Code Online (Sandbox Code Playgroud)

这是编译,但任何合理的决定T应该产生的实际类型Throwable,并要求foo() throws Throwable.Eclipse似乎认为它是RuntimeException.我想知道javac发生了什么.如果这是javacthrows条款中处理类型参数的错误,那么这个问题的答案将允许我证明它.

Vic*_*ero 5

可以查看 javac 推断/解析的详细信息等。为此,您需要使用隐藏/不支持/未记录的选项:-XDverboseResolution。如果想要查看所有信息,则要传递的值是“all”,如下所示:-XDverboseResolution=all。如果只想查看通用方法的实例化,则选项为:-XDverboseResolution=deferred-inference。对于原始问题中的代码,我得到以下输出:

命令:javac -XDverboseResolution=deferred-inference Scratch.java

输出:

Scratch.java:6: Note: Deferred instantiation of method <T>sneakyThrow(Throwable)
    sneakyThrow(new Exception());
               ^
  instantiated signature: (Throwable)void
  target-type: <none>
  where T is a type-variable:
    T extends Throwable declared in method <T>sneakyThrow(Throwable)
Note: Scratch.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
Run Code Online (Sandbox Code Playgroud)

从这个输出中,您可以推断 T 已实例化为 Throwable。

我希望这就是您正在寻找的。

  • @JornVernee,嗨,该标志仍​​然存在,但已重命名,这当然不是 API 的一部分。要继续使用它,您应该执行以下操作:`javac --debug=verboseResolution=all` (4认同)