# java.lang.invoke

***

**1. Dynamic Method Invocation:**

```java
CallSite site = LambdaMetafactory.metafactory(
    java.lang.invoke.MethodHandles.lookup(),
    "hello",
    MethodType.methodType(void.class, String.class),
    LambdaMetafactory.FLAG_PUBLIC | LambdaMetafactory.FLAG_FINAL,
    MethodType.methodType(String.class),
    "sayHello"
);
site.dynamicInvoker().invoke("John"); // Prints "Hello John!"
```

**2. Customizing Method Invocation Logic:**

```java
MethodHandle mh = MethodHandles.lookup().findVirtual(
    String.class, "toUpperCase", MethodType.methodType(String.class)
);
MethodHandle mhCustom = MethodHandles.filterArguments(
    mh, 0, String.class, String::toUpperCase
);
System.out.println(mhCustom.invoke("hello")); // Prints "HELLO"
```

**3. Partial Application (Currying):**

```java
MethodHandle concatHandle = MethodHandles.lookup().findVirtual(
    String.class, "concat", MethodType.methodType(String.class, String.class)
);
MethodHandle prependHandle = MethodHandles.insertArguments(
    concatHandle, 1, "Hello "
);
System.out.println(prependHandle.invoke("World")); // Prints "Hello World"
```

**4. Method Linking:**

```java
MethodHandle printlnHandle = MethodHandles.lookup().findVirtual(
    java.io.PrintStream.class, "println", MethodType.methodType(void.class, Object.class)
);
MethodHandle toUpperCaseHandle = MethodHandles.lookup().findStatic(
    String.class, "toUpperCase", MethodType.methodType(String.class, String.class)
);
MethodHandle composed = MethodHandles.filterArguments(
    printlnHandle, 1, toUpperCaseHandle
);
composed.invoke("hello"); // Prints "HELLO" to System.out
```

**5. Auto-Unboxing:**

```java
MethodHandle plusHandle = MethodHandles.lookup().findStatic(
    Integer.class, "sum", MethodType.methodType(Integer.class, int.class, int.class)
);
MethodHandle unboxedHandle = MethodHandles.explicitCastArguments(
    plusHandle, MethodType.methodType(Integer.class, Integer.class, Integer.class)
);
System.out.println(unboxedHandle.invoke(4, 5)); // Prints 9
```

**6. Variable-Arity Method Invocation (InvokeDynamic):**

```java
InvokeDynamic invoker = (args) -> String.join(",", args);
MethodHandle handle = invoker.bindTo("A", "B", "C");
System.out.println(handle.invoke()); // Prints "A,B,C"
```

**7. Exception Handling with Method Handles:**

```java
MethodHandle mh = MethodHandles.lookup().findStatic(
    java.lang.Math.class, "log", MethodType.methodType(double.class, double.class)
);
MethodHandle fallbackHandle = MethodHandles.lookup().findVirtual(
    java.lang.Double.class, "isInfinite", MethodType.methodType(boolean.class)
);
MethodHandle catchHandle = MethodHandles.guardWithTest(
    mh, fallbackHandle, MethodHandles.ifInstanceOf(Double.class)
);
System.out.println(catchHandle.invoke(Double.POSITIVE_INFINITY)); // Prints "true"
```

**8. Customizing Java Bean Access:**

```java
MethodHandle getterHandle = MethodHandles.lookup()
    .findGetter(Foo.class, "name", String.class)
    .filterArguments(1, String.class, String::toUpperCase);
System.out.println(getterHandle.invoke(new Foo("John"))); // Prints "JOHN"
```

**9. High-Performance Memory Access:**

```java
ByteBuffer buffer = ByteBuffer.allocate(1024);
MethodHandle getHandle = MethodHandles.lookup()
    .findVirtual(java.nio.Buffer.class, "get", MethodType.methodType(byte.class, int.class));
for (int i = 0; i < buffer.capacity(); i++) {
    System.out.print(getHandle.invokeExact(buffer, i) + ", ");
}
```

**10. Reflective Operations:**

```java
MethodHandle mh = MethodHandles.lookup()
    .findConstructor(Foo.class, MethodType.methodType(void.class, String.class));
Foo foo = (Foo) mh.invokeExact("John");
System.out.println(foo.getName()); // Prints "John"
```

**11. Method Reflection:**

```java
MethodHandle mh = MethodHandles.lookup()
    .findVirtual(java.lang.String.class, "compareTo", MethodType.methodType(int.class, String.class));
System.out.println(mh.reflect(new Foo("John"), "John").invoke()); // Prints 0
```

**12. Dynamic Method Lookup:**

```java
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle mh = lookup.in(Foo.class)
    .findVirtual("getName", MethodType.methodType(String.class));
System.out.println(mh.invoke(new Foo("John"))); // Prints "John"
```

**13. Class Casting:**

```java
MethodHandle mh = MethodHandles.lookup()
    .findVirtual(java.lang.Object.class, "getClass", MethodType.methodType(Class.class));
MethodHandle castHandle = MethodHandles.castArguments(
    mh, 0, Foo.class
);
Foo foo = (Foo) castHandle.invokeExact(new Foo("John"));
System.out.println(foo.getName()); // Prints "John"
```

**14. Array Element Access:**

```java
MethodHandle mh = MethodHandles.lookup()
    .findStatic(java.lang.Math.class, "sqrt", MethodType.methodType(double.class, double.class));
MethodHandle arrayHandle = MethodHandles.arrayElementGetter(double[].class);
double[] array = {1, 4, 9};
for (int i = 0; i < array

```
