Proposed API for JEP 259: Stack-Walking API
Mandy Chung
mandy.chung at oracle.com
Wed Nov 18 16:00:35 UTC 2015
This is the update javadoc of getCallerClass. Thanks for all the feedback and suggestion. I have to finalize this API today to make the FC date :)
/**
* Gets the {@code Class} object of the caller invoking the method
* that calls this {@code getCallerClass} method.
*
* <p> Reflection frames, {@link java.lang.invoke.MethodHandle} and
* hidden frames are filtered regardless of the
* {@link Option#SHOW_REFLECT_FRAMES SHOW_REFLECT_FRAMES}
* and {@link Option#SHOW_HIDDEN_FRAMES SHOW_HIDDEN_FRAMES} options
* this {@code StackWalker} has been configured.
*
* <p> This method throws {@code UnsupportedOperationException}
* if this {@code StackWalker} is not configured with
* {@link Option#RETAIN_CLASS_REFERENCE RETAIN_CLASS_REFERENCE} option,
* This method should be called when a caller frame is present. If
* it is called from the last frame on the stack;
* {@code IllegalStateException} will be thrown.
*
* @apiNote
* For example, {@code Util::getResourceBundle} loads a resource bundle
* on behalf of the caller. It calls this {@code getCallerClass} method
* to find the method calling {@code Util::getResourceBundle} and use the caller's
* class loader to load the resource bundle. The caller class in this example
* is the {@code MyTool} class.
*
* <pre>{@code
* class Util {
* private final StackWalker walker = StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE);
* public ResourceBundle getResourceBundle(String bundleName) {
* Class<?> caller = walker.getCallerClass();
* return ResourceBundle.getBundle(bundleName, Locale.getDefault(), caller.getClassLoader());
* }
* }
*
* class MyTool {
* private final Util util = new Util();
* private void init() {
* ResourceBundle rb = util.getResourceBundle("mybundle");
* }
* }
* }</pre>
*
* An equivalent way to find the caller class using the
* {@link StackWalker#walk walk} method is as follows
* (filtering the reflection frames, {@code MethodHandle} and hidden frames
* not shown below):
* <pre>{@code
* Optional<Class<?>> caller = walker.walk(s ->
* s.map(StackFrame::getDeclaringClass)
* .skip(2)
* .findFirst());
* }</pre>
*
* When the {@code getCallerClass} method is called from a method that
* is the last frame on the stack,
* for example, {@code static public void main} method launched by the
* {@code java} launcher or a method invoked from a JNI attached thread.
* {@code IllegalStateException} is thrown.
*
* @return {@code Class} object of the caller's caller invoking this method.
*
* @throws UnsupportedOperationException if this {@code StackWalker}
* is not configured with {@link Option#RETAIN_CLASS_REFERENCE
* Option.RETAIN_CLASS_REFERENCE}.
* @throws IllegalStateException if there is no caller frame, i.e.
* when this {@code getCallerClass} method is called from a method
* which is the last frame on the stack.
*/
More information about the core-libs-dev
mailing list