Added in [API level 26](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

# MethodHandleInfo

` public interface MethodHandleInfo `   
` `

|---|
| java.lang.invoke.MethodHandleInfo |

<br />

*** ** * ** ***

A symbolic reference obtained by cracking a direct method handle into its consitutent symbolic parts. To crack a direct method handle, call `https://developer.android.com/reference/java/lang/invoke/MethodHandles.Lookup#revealDirect(java.lang.invoke.MethodHandle)`.

# Direct Method Handles

A *direct method handle* represents a method, constructor, or field without any intervening argument bindings or other transformations. The method, constructor, or field referred to by a direct method handle is called its *underlying member* . Direct method handles may be obtained in any of these ways:

- By executing an `ldc` instruction on a `CONSTANT_MethodHandle` constant. (See the Java Virtual Machine Specification, sections 4.4.8 and 5.4.3.)
- By calling one of the [Lookup Factory Methods](https://developer.android.com/reference/java/lang/invoke/MethodHandles.Lookup#lookups), such as `https://developer.android.com/reference/java/lang/invoke/MethodHandles.Lookup#findVirtual(java.lang.Class<?>,%20java.lang.String,%20java.lang.invoke.MethodType)`, to resolve a symbolic reference into a method handle. A symbolic reference consists of a class, name string, and type.
- By calling the factory method `https://developer.android.com/reference/java/lang/invoke/MethodHandles.Lookup#unreflect(java.lang.reflect.Method)` or `https://developer.android.com/reference/java/lang/invoke/MethodHandles.Lookup#unreflectSpecial(java.lang.reflect.Method,%20java.lang.Class<?>)` to convert a `https://developer.android.com/reference/java/lang/reflect/Method` into a method handle.
- By calling the factory method `https://developer.android.com/reference/java/lang/invoke/MethodHandles.Lookup#unreflectConstructor(java.lang.reflect.Constructor<?>)` to convert a `https://developer.android.com/reference/java/lang/reflect/Constructor` into a method handle.
- By calling the factory method `https://developer.android.com/reference/java/lang/invoke/MethodHandles.Lookup#unreflectGetter(java.lang.reflect.Field)` or `https://developer.android.com/reference/java/lang/invoke/MethodHandles.Lookup#unreflectSetter(java.lang.reflect.Field)` to convert a `https://developer.android.com/reference/java/lang/reflect/Field` into a method handle.

# Restrictions on Cracking

Given a suitable `Lookup` object, it is possible to crack any direct method handle to recover a symbolic reference for the underlying method, constructor, or field. Cracking must be done via a `Lookup` object equivalent to that which created the target method handle, or which has enough access permissions to recreate an equivalent method handle.

If the underlying method is [caller sensitive](https://developer.android.com/reference/java/lang/invoke/MethodHandles.Lookup#callsens), the direct method handle will have been "bound" to a particular caller class, the [lookup class](https://developer.android.com/reference/java/lang/invoke/MethodHandles.Lookup#lookupClass()) of the lookup object used to create it. Cracking this method handle with a different lookup class will fail even if the underlying method is public (like `Class.forName`).

The requirement of lookup object matching provides a "fast fail" behavior for programs which may otherwise trust erroneous revelation of a method handle with symbolic information (or caller binding) from an unexpected scope. Use `https://developer.android.com/reference/java/lang/invoke/MethodHandles#reflectAs(java.lang.Class<T>,%20java.lang.invoke.MethodHandle)` to override this limitation.

# Reference kinds

The [Lookup Factory Methods](https://developer.android.com/reference/java/lang/invoke/MethodHandles.Lookup#lookups) correspond to all major use cases for methods, constructors, and fields. These use cases may be distinguished using small integers as follows:

| reference kind | descriptive name | scope | member | behavior |
|---|---|---|---|---|
| `1` | `REF_getField` | `class` | `FT f;` | `(T) this.f;` |
| `2` | `REF_getStatic` | `class` or `interface` | `static` `FT f;` | `(T) C.f;` |
| `3` | `REF_putField` | `class` | `FT f;` | `this.f = x;` |
| `4` | `REF_putStatic` | `class` | `static` `FT f;` | `C.f = arg;` |
| `5` | `REF_invokeVirtual` | `class` | `T m(A*);` | `(T) this.m(arg*);` |
| `6` | `REF_invokeStatic` | `class` or `interface` | `static` `T m(A*);` | `(T) C.m(arg*);` |
| `7` | `REF_invokeSpecial` | `class` or `interface` | `T m(A*);` | `(T) super.m(arg*);` |
| `8` | `REF_newInvokeSpecial` | `class` | `C(A*);` | `new C(arg*);` |
| `9` | `REF_invokeInterface` | `interface` | `T m(A*);` | `(T) this.m(arg*);` |

<br />

## Summary

| ### Constants ||
|---|---|
| `int` | `https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#REF_getField` A direct method handle reference kind, as defined in the [table above](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refkinds). |
| `int` | `https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#REF_getStatic` A direct method handle reference kind, as defined in the [table above](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refkinds). |
| `int` | `https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#REF_invokeInterface` A direct method handle reference kind, as defined in the [table above](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refkinds). |
| `int` | `https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#REF_invokeSpecial` A direct method handle reference kind, as defined in the [table above](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refkinds). |
| `int` | `https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#REF_invokeStatic` A direct method handle reference kind, as defined in the [table above](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refkinds). |
| `int` | `https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#REF_invokeVirtual` A direct method handle reference kind, as defined in the [table above](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refkinds). |
| `int` | `https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#REF_newInvokeSpecial` A direct method handle reference kind, as defined in the [table above](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refkinds). |
| `int` | `https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#REF_putField` A direct method handle reference kind, as defined in the [table above](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refkinds). |
| `int` | `https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#REF_putStatic` A direct method handle reference kind, as defined in the [table above](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refkinds). |

| ### Public methods ||
|---|---|
| ` abstract https://developer.android.com/reference/java/lang/Class<?>` | ` https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#getDeclaringClass()() ` Returns the class in which the cracked method handle's underlying member was defined. |
| ` abstract https://developer.android.com/reference/java/lang/invoke/MethodType` | ` https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#getMethodType()() ` Returns the nominal type of the cracked symbolic reference, expressed as a method type. |
| ` abstract int` | ` https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#getModifiers()() ` Returns the access modifiers of the underlying member. |
| ` abstract https://developer.android.com/reference/java/lang/String` | ` https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#getName()() ` Returns the name of the cracked method handle's underlying member. |
| ` abstract int` | ` https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#getReferenceKind()() ` Returns the reference kind of the cracked method handle, which in turn determines whether the method handle's underlying member was a constructor, method, or field. |
| ` default boolean` | ` https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#isVarArgs()() ` Determines if the underlying member was a variable arity method or constructor. |
| ` static boolean` | ` https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refKindIsField(int)(int refKind) ` *This method was deprecated in API level 29. This internal method was accidentally added to API 26 and must not be used. No replacement is available but it is possible to replicate using information from the [table above](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refkinds), e.g. `refKind >= 1 && refKind <= 4`. There are no guarantees that this logic will work if future versions extend the table.* |
| ` static boolean` | ` https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refKindIsValid(int)(int refKind) ` *This method was deprecated in API level 29. This internal method was accidentally added to API 26 and must not be used. No replacement is available but it is possible to replicate using information from the [table above](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refkinds), e.g. `refKind >= 1 && refKind <= 9`. There are no guarantees that this logic will work if future versions extend the table.* |
| ` static https://developer.android.com/reference/java/lang/String` | ` https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refKindName(int)(int refKind) ` *This method was deprecated in API level 29. This internal method was accidentally added to API 26 and must not be used. Use `https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#referenceKindToString(int)` instead.* |
| ` static https://developer.android.com/reference/java/lang/String` | ` https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#referenceKindToString(int)(int referenceKind) ` Returns the descriptive name of the given reference kind, as defined in the [table above](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refkinds). |
| ` abstract <T extends https://developer.android.com/reference/java/lang/reflect/Member> T` | ` https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#reflectAs(java.lang.Class<T>,%20java.lang.invoke.MethodHandles.Lookup)(https://developer.android.com/reference/java/lang/Class<T> expected, https://developer.android.com/reference/java/lang/invoke/MethodHandles.Lookup lookup) ` Reflects the underlying member as a method, constructor, or field object. |
| ` static https://developer.android.com/reference/java/lang/String` | ` https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#toString(int,%20java.lang.Class<?>,%20java.lang.String,%20java.lang.invoke.MethodType)(int kind, https://developer.android.com/reference/java/lang/Class<?> defc, https://developer.android.com/reference/java/lang/String name, https://developer.android.com/reference/java/lang/invoke/MethodType type) ` Returns a string representation for a `MethodHandleInfo`, given the four parts of its symbolic reference. |

## Constants

### REF_getField

Added in [API level 26](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public static final int REF_getField
```

A direct method handle reference kind, as defined in the [table above](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refkinds).

<br />

Constant Value: 1 (0x00000001)

### REF_getStatic

Added in [API level 26](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public static final int REF_getStatic
```

A direct method handle reference kind, as defined in the [table above](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refkinds).

<br />

Constant Value: 2 (0x00000002)

### REF_invokeInterface

Added in [API level 26](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public static final int REF_invokeInterface
```

A direct method handle reference kind, as defined in the [table above](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refkinds).

<br />

Constant Value: 9 (0x00000009)

### REF_invokeSpecial

Added in [API level 26](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public static final int REF_invokeSpecial
```

A direct method handle reference kind, as defined in the [table above](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refkinds).

<br />

Constant Value: 7 (0x00000007)

### REF_invokeStatic

Added in [API level 26](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public static final int REF_invokeStatic
```

A direct method handle reference kind, as defined in the [table above](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refkinds).

<br />

Constant Value: 6 (0x00000006)

### REF_invokeVirtual

Added in [API level 26](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public static final int REF_invokeVirtual
```

A direct method handle reference kind, as defined in the [table above](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refkinds).

<br />

Constant Value: 5 (0x00000005)

### REF_newInvokeSpecial

Added in [API level 26](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public static final int REF_newInvokeSpecial
```

A direct method handle reference kind, as defined in the [table above](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refkinds).

<br />

Constant Value: 8 (0x00000008)

### REF_putField

Added in [API level 26](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public static final int REF_putField
```

A direct method handle reference kind, as defined in the [table above](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refkinds).

<br />

Constant Value: 3 (0x00000003)

### REF_putStatic

Added in [API level 26](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public static final int REF_putStatic
```

A direct method handle reference kind, as defined in the [table above](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refkinds).

<br />

Constant Value: 4 (0x00000004)

## Public methods

### getDeclaringClass

Added in [API level 26](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public abstract Class<?> getDeclaringClass ()
```

Returns the class in which the cracked method handle's underlying member was defined.

<br />

| Returns ||
|---|---|
| `https://developer.android.com/reference/java/lang/Class<?>` | the declaring class of the underlying member <br /> |

### getMethodType

Added in [API level 26](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public abstract MethodType getMethodType ()
```

Returns the nominal type of the cracked symbolic reference, expressed as a method type. If the reference is to a constructor, the return type will be `void`. If it is to a non-static method, the method type will not mention the `this` parameter. If it is to a field and the requested access is to read the field, the method type will have no parameters and return the field type. If it is to a field and the requested access is to write the field, the method type will have one parameter of the field type and return `void`.

Note that original direct method handle may include a leading `this` parameter, or (in the case of a constructor) will replace the `void` return type with the constructed class. The nominal type does not include any `this` parameter, and (in the case of a constructor) will return `void`.

<br />

| Returns ||
|---|---|
| `https://developer.android.com/reference/java/lang/invoke/MethodType` | the type of the underlying member, expressed as a method type <br /> |

### getModifiers

Added in [API level 26](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public abstract int getModifiers ()
```

Returns the access modifiers of the underlying member.

<br />

| Returns ||
|---|---|
| `int` | the Java language modifiers for underlying member, or -1 if the member cannot be accessed <br /> |

**See also:**

- `https://developer.android.com/reference/java/lang/reflect/Modifier`
- `https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#reflectAs(java.lang.Class<T>,%20java.lang.invoke.MethodHandles.Lookup)`

### getName

Added in [API level 26](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public abstract String getName ()
```

Returns the name of the cracked method handle's underlying member. This is `"<init>"` if the underlying member was a constructor, else it is a simple method name or field name.

<br />

| Returns ||
|---|---|
| `https://developer.android.com/reference/java/lang/String` | the simple name of the underlying member <br /> |

### getReferenceKind

Added in [API level 26](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public abstract int getReferenceKind ()
```

Returns the reference kind of the cracked method handle, which in turn determines whether the method handle's underlying member was a constructor, method, or field. See the [table above](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refkinds) for definitions.

<br />

| Returns ||
|---|---|
| `int` | the integer code for the kind of reference used to access the underlying member <br /> |

### isVarArgs

Added in [API level 26](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public boolean isVarArgs ()
```

Determines if the underlying member was a variable arity method or constructor. Such members are represented by method handles that are varargs collectors.

<br />

##### Implementation Requirements:

- This produces a result equivalent to:

      getReferenceKind() >= REF_invokeVirtual && Modifier.isTransient(getModifiers())

| Returns ||
|---|---|
| `boolean` | `true` if and only if the underlying member was declared with variable arity. <br /> |

### refKindIsField

Added in [API level 26](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)   
Deprecated in [API level 29](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public static boolean refKindIsField (int refKind)
```

<br />

**This method was deprecated in API level 29.**   

This internal method was accidentally added to API 26 and must not be used. No replacement is available but it is possible to replicate using information from the [table above](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refkinds), e.g. `refKind >= 1 && refKind <= 4`. There are no guarantees that this logic will work if future versions extend the table.

<br />

<br />

| Parameters ||
|---|---|
| `refKind` | `int` <br /> |

| Returns ||
|---|---|
| `boolean` | <br /> |

### refKindIsValid

Added in [API level 26](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)   
Deprecated in [API level 29](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public static boolean refKindIsValid (int refKind)
```

<br />

**This method was deprecated in API level 29.**   

This internal method was accidentally added to API 26 and must not be used. No replacement is available but it is possible to replicate using information from the [table above](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refkinds), e.g. `refKind >= 1 && refKind <= 9`. There are no guarantees that this logic will work if future versions extend the table.

<br />

<br />

| Parameters ||
|---|---|
| `refKind` | `int` <br /> |

| Returns ||
|---|---|
| `boolean` | <br /> |

### refKindName

Added in [API level 26](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)   
Deprecated in [API level 29](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public static String refKindName (int refKind)
```

<br />

**This method was deprecated in API level 29.**   

This internal method was accidentally added to API 26 and must not be used. Use `https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#referenceKindToString(int)` instead.

<br />

<br />

| Parameters ||
|---|---|
| `refKind` | `int` <br /> |

| Returns ||
|---|---|
| `https://developer.android.com/reference/java/lang/String` | <br /> |

### referenceKindToString

Added in [API level 26](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public static String referenceKindToString (int referenceKind)
```

Returns the descriptive name of the given reference kind, as defined in the [table above](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refkinds). The conventional prefix "REF_" is omitted.

<br />

| Parameters ||
|---|---|
| `referenceKind` | `int`: an integer code for a kind of reference used to access a class member <br /> |

| Returns ||
|---|---|
| `https://developer.android.com/reference/java/lang/String` | a mixed-case string such as `"getField"` <br /> |

| Throws ||
|---|---|
| `https://developer.android.com/reference/java/lang/IllegalArgumentException` | if the argument is not a valid [reference kind number](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refkinds) |

### reflectAs

Added in [API level 26](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public abstract T reflectAs (Class<T> expected, 
                MethodHandles.Lookup lookup)
```

Reflects the underlying member as a method, constructor, or field object. If the underlying member is public, it is reflected as if by `getMethod`, `getConstructor`, or `getField`. Otherwise, it is reflected as if by `getDeclaredMethod`, `getDeclaredConstructor`, or `getDeclaredField`. The underlying member must be accessible to the given lookup object.

<br />

| Parameters ||
|---|---|
| `expected` | `Class`: a class object representing the desired result type `T` <br /> |
| `lookup` | `MethodHandles.Lookup`: the lookup object that created this MethodHandleInfo, or one with equivalent access privileges <br /> |

| Returns ||
|---|---|
| `T` | a reference to the method, constructor, or field object <br /> |

| Throws ||
|---|---|
| `https://developer.android.com/reference/java/lang/ClassCastException` | if the member is not of the expected type |
| `https://developer.android.com/reference/java/lang/IllegalArgumentException` | if the underlying member is not accessible to the given lookup object |
| `https://developer.android.com/reference/java/lang/NullPointerException` | if either argument is `null` |

### toString

Added in [API level 26](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public static String toString (int kind, 
                Class<?> defc, 
                String name, 
                MethodType type)
```

Returns a string representation for a `MethodHandleInfo`, given the four parts of its symbolic reference. This is defined to be of the form `"RK C.N:MT"`, where `RK` is the [reference kind string](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#referenceKindToString(int)) for `kind`, `C` is the [name](https://developer.android.com/reference/java/lang/Class#getName()) of `defc` `N` is the `name`, and `MT` is the `type`. These four values may be obtained from the [reference kind](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#getReferenceKind()), [declaring class](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#getDeclaringClass()), [member name](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#getName()), and [method type](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#getMethodType()) of a `MethodHandleInfo` object.

<br />

##### Implementation Requirements:

- This produces a result equivalent to:

      String.format("%s %s.%s:%s", referenceKindToString(kind), defc.getName(), name, type)

| Parameters ||
|---|---|
| `kind` | `int`: the [reference kind](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#getReferenceKind()) part of the symbolic reference <br /> |
| `defc` | `Class`: the [declaring class](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#getDeclaringClass()) part of the symbolic reference <br /> |
| `name` | `String`: the [member name](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#getName()) part of the symbolic reference <br /> |
| `type` | `MethodType`: the [method type](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#getMethodType()) part of the symbolic reference <br /> |

| Returns ||
|---|---|
| `https://developer.android.com/reference/java/lang/String` | a string of the form `"RK C.N:MT"` <br /> |

| Throws ||
|---|---|
| `https://developer.android.com/reference/java/lang/IllegalArgumentException` | if the first argument is not a valid [reference kind number](https://developer.android.com/reference/java/lang/invoke/MethodHandleInfo#refkinds) |
| `https://developer.android.com/reference/java/lang/NullPointerException` | if any reference argument is `null` |