Is it possible to get javac
to output information about the types it's inferring for method invocations?
For example, I want to know what is inferred for the formal type T
in the invocation of bar
.
private static <T> void bar() { ... }
public void foo() {
bar();
}
I was exploring javac -Xprint
and friends, but can't find anything that exposes this level of detail.
EDIT Example. I didn't want to put this up originally because it'll complicate answers. I'm primarily interested in getting debug info out of javac
. Anyway, this was the motivating example:
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());
}
}
This compiles, but any reasonable decision as to the actual type of T
should yield Throwable
, and require that foo() throws Throwable
. Eclipse seems to think it's RuntimeException
. I want to know what javac
thinks is happening. If it's a bug in javac
's processing of type parameters in the throws
clause, the answer to this question would allow me to prove it.
Type inference is a Java compiler's ability to look at each method invocation and corresponding declaration to determine the type argument (or arguments) that make the invocation applicable.
Type inference is the ability to automatically deduce, either partially or fully, the type of an expression at compile time. The compiler is often able to infer the type of a variable or the type signature of a function, without explicit type annotations having been given.
So, I can imagine that type inference was probably not supported because Java was aimed at programmers coming from C++, Pascal, or other mainstream languages that did not have it (principle of least surprise).
It's possible to see with a lot of detail what javac has inferred / resolved etc. To do that you need to use the hidden / unsupported / undocumented option: -XDverboseResolution. If one want to see all the information then the value to pass is 'all' as in: -XDverboseResolution=all. If one only want to see the instantiation of the generic methods then the option is: -XDverboseResolution=deferred-inference. For the code in the original question I get the following output:
command: javac -XDverboseResolution=deferred-inference Scratch.java
output:
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.
From this output you can infer that T has been instantiated to Throwable.
I hope this is what you were looking for.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With