MethodHandles.TryFinally(MethodHandle, MethodHandle) Method
Definition
Important
Some information relates to prerelease product that may be substantially modified before it’s released. Microsoft makes no warranties, express or implied, with respect to the information provided here.
Makes a method handle that adapts a target
method handle by wrapping it in a try-finally
block.
[Android.Runtime.Register("tryFinally", "(Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/MethodHandle;", "", ApiSince=33)]
public static Java.Lang.Invoke.MethodHandle? TryFinally (Java.Lang.Invoke.MethodHandle? target, Java.Lang.Invoke.MethodHandle? cleanup);
[<Android.Runtime.Register("tryFinally", "(Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/MethodHandle;", "", ApiSince=33)>]
static member TryFinally : Java.Lang.Invoke.MethodHandle * Java.Lang.Invoke.MethodHandle -> Java.Lang.Invoke.MethodHandle
Parameters
- target
- MethodHandle
the handle whose execution is to be wrapped in a try
block.
- cleanup
- MethodHandle
the handle that is invoked in the finally block.
Returns
a method handle embodying the try-finally
block composed of the two arguments.
- Attributes
Remarks
Makes a method handle that adapts a target
method handle by wrapping it in a try-finally
block. Another method handle, cleanup
, represents the functionality of the finally
block. Any exception thrown during the execution of the target
handle will be passed to the cleanup
handle. The exception will be rethrown, unless cleanup
handle throws an exception first. The value returned from the cleanup
handle's execution will be the result of the execution of the try-finally
handle.
The cleanup
handle will be passed one or two additional leading arguments. The first is the exception thrown during the execution of the target
handle, or null
if no exception was thrown. The second is the result of the execution of the target
handle, or, if it throws an exception, a null
, zero, or false
value of the required type is supplied as a placeholder. The second argument is not present if the target
handle has a void
return type. (Note that, except for argument type conversions, combinators represent void
values in parameter lists by omitting the corresponding paradoxical arguments, not by inserting null
or zero values.)
The target
and cleanup
handles must have the same corresponding argument and return types, except that the cleanup
handle may omit trailing arguments. Also, the cleanup
handle must have one or two extra leading parameters:<ul> <li>a Throwable
, which will carry the exception thrown by the target
handle (if any); and <li>a parameter of the same type as the return type of both target
and cleanup
, which will carry the result from the execution of the target
handle. This parameter is not present if the target
returns void
. </ul>
The pseudocode for the resulting adapter looks as follows. In the code, V
represents the result type of the try/finally
construct; A
/a
, the types and values of arguments to the resulting handle consumed by the cleanup; and B
/b
, those of arguments to the resulting handle discarded by the cleanup. <blockquote>
{@code
V target(A..., B...);
V cleanup(Throwable, V, A...);
V adapter(A... a, B... b) {
V result = (zero value for V);
Throwable throwable = null;
try {
result = target(a..., b...);
} catch (Throwable t) {
throwable = t;
throw t;
} finally {
result = cleanup(throwable, result, a...);
}
return result;
}
}
</blockquote>
Note that the saved arguments (a...
in the pseudocode) cannot be modified by execution of the target, and so are passed unchanged from the caller to the cleanup, if it is invoked.
The target and cleanup must return the same type, even if the cleanup always throws. To create such a throwing cleanup, compose the cleanup logic with #throwException throwException
, in order to create a method handle of the correct return type.
Note that tryFinally
never converts exceptions into normal returns. In rare cases where exceptions must be converted in that way, first wrap the target with #catchException(MethodHandle, Class, MethodHandle)
to capture an outgoing exception, and then wrap with tryFinally
.
It is recommended that the first parameter type of cleanup
be declared Throwable
rather than a narrower subtype. This ensures cleanup
will always be invoked with whatever exception that target
throws. Declaring a narrower type may result in a ClassCastException
being thrown by the try-finally
handle if the type of the exception thrown by target
is not assignable to the first parameter type of cleanup
. Note that various exception types of VirtualMachineError
, LinkageError
, and RuntimeException
can in principle be thrown by almost any kind of Java code, and a finally clause that catches (say) only IOException
would mask any of the others behind a ClassCastException
.
Added in 9.
Portions of this page are modifications based on work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.