All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.dongliu.dbutils.internal.reflect.InstanceMethod Maven / Gradle / Ivy

package net.dongliu.dbutils.internal.reflect;

import net.dongliu.dbutils.internal.Exceptions;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Objects;

/**
 * Method of instance of a class
 *
 * @author Liu Dong
 */
public class InstanceMethod extends AbstractMethod {
    private final Method method;
    private final MethodHandle methodHandle;

    public InstanceMethod(Method method) {
        Objects.requireNonNull(method);
        if (Modifier.isStatic(method.getModifiers())) {
            throw new IllegalArgumentException("Method should not be static");
        }
        this.method = method;
        this.methodHandle = getHandle(method);
    }

    private MethodHandle getHandle(Method method) {
        method.setAccessible(true);
        MethodHandles.Lookup lookup = MethodHandles.lookup();
        try {
            // private function can invoke special instead of invoke virtual, however we can not use  unreflectSpecial
            // when do not have private access to the class
            return lookup.unreflect(method);
        } catch (IllegalAccessException e) {
            throw Exceptions.sneakyThrow(e);
        }
    }


    public Method getMethod() {
        return method;
    }

    /**
     * Return method name
     */
    public String name() {
        return method.getName();
    }

    /**
     * Invoke method with return values
     */
    public Object call(Object instance, Object... args) {
        if (method.getReturnType() == void.class) {
            // no return value
            run(instance, args);
            return null;
        }
        args = concat(Objects.requireNonNull(instance), args);
        try {
            return methodHandle.invokeWithArguments(args);
        } catch (Throwable throwable) {
            throw Exceptions.sneakyThrow(throwable);
        }
    }

    /**
     * Invoke method with no value
     */
    public void run(Object instance, Object... args) {
        args = concat(Objects.requireNonNull(instance), args);
        try {
            methodHandle.invokeWithArguments(args);
        } catch (Throwable throwable) {
            throw Exceptions.sneakyThrow(throwable);
        }
    }

    private Object[] concat(Object instance, Object[] args) {
        if (args.length == 0) {
            return new Object[]{instance};
        }
        Object[] objects = new Object[args.length + 1];
        objects[0] = instance;
        System.arraycopy(args, 0, objects, 1, args.length);
        return objects;
    }

    /**
     * Invoke method with return values
     */
    public Object call(Object instance) {
        if (method.getReturnType() == void.class) {
            // no return value
            run(instance);
            return null;
        }
        try {
            return methodHandle.invoke(instance);
        } catch (Throwable throwable) {
            throw Exceptions.sneakyThrow(throwable);
        }
    }

    /**
     * Invoke method with no value
     */
    public void run(Object instance) {
        try {
            methodHandle.invoke(instance);
        } catch (Throwable throwable) {
            throw Exceptions.sneakyThrow(throwable);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy