@Override
    @SuppressWarnings({"rawtypes", "unchecked"})
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        final String methodName = method.getName();
        int parameterCount = method.getParameterCount();

        Class<?> returnType = method.getReturnType();
        if (parameterCount == 1) {
            if ("equals".equals(methodName)) {
                return this.equals(args[0]);
            }

            Class proxyInterface = null;
            Class<?>[] interfaces = proxy.getClass().getInterfaces();
            if (interfaces.length == 1) {
                proxyInterface = interfaces[0];
            }

            if (returnType != void.class && returnType != proxyInterface) {
                throw new JSONException("This method '" + methodName + "' is not a setter");
            }

            String name = getJSONFieldName(method);

            if (name == null) {
                name = methodName;

                if (!name.startsWith("set")) {
                    throw new JSONException("This method '" + methodName + "' is not a setter");
                }

                name = name.substring(3);
                if (name.length() == 0) {
                    throw new JSONException("This method '" + methodName + "' is an illegal setter");
                }
                name = Character.toLowerCase(name.charAt(0)) + name.substring(1);
            }

            put(name, args[0]);

            if (returnType != void.class) {
                return proxy;
            }

            return null;
        }

        if (parameterCount == 0) {
            if (returnType == void.class) {
                throw new JSONException("This method '" + methodName + "' is not a getter");
            }

            String name = getJSONFieldName(method);

            Object value;
            if (name == null) {
                name = methodName;
                boolean with = false;
                int prefix;
                if ((name.startsWith("get") || (with = name.startsWith("with")))
                        && name.length() > (prefix = with ? 4 : 3)
                ) {
                    char[] chars = new char[name.length() - prefix];
                    name.getChars(prefix, name.length(), chars, 0);
                    if (chars[0] >= 'A' && chars[0] <= 'Z') {
                        chars[0] = (char) (chars[0] + 32);
                    }
                    String fieldName = new String(chars);
                    if (fieldName.isEmpty()) {
                        throw new JSONException("This method '" + methodName + "' is an illegal getter");
                    }

                    value = get(fieldName);
                    if (value == null) {
                        return null;
                    }
                } else if (name.startsWith("is")) {
                    if ("isEmpty".equals(name)) {
                        value = get("empty");
                        if (value == null) {
                            return this.isEmpty();
                        }
                    } else {
                        name = name.substring(2);
                        if (name.isEmpty()) {
                            throw new JSONException("This method '" + methodName + "' is an illegal getter");
                        }
                        name = Character.toLowerCase(name.charAt(0)) + name.substring(1);

                        value = get(name);
                        if (value == null) {
                            return false;
                        }
                    }
                } else if ("hashCode".equals(name)) {
                    return this.hashCode();
                } else if ("toString".equals(name)) {
                    return this.toString();
                } else if (name.startsWith("entrySet")) {
                    return this.entrySet();
                } else if ("size".equals(name)) {
                    return this.size();
                } else {
                    Class<?> declaringClass = method.getDeclaringClass();
                    if (declaringClass.isInterface()
                            && !Modifier.isAbstract(method.getModifiers())
                            && !ANDROID
                            && !GRAAL
                    ) {
                        // interface default method
                        MethodHandles.Lookup lookup = JDKUtils.trustedLookup(declaringClass);
                        MethodHandle methodHandle = lookup.findSpecial(
                                declaringClass,
                                method.getName(),
                                MethodType.methodType(returnType),
                                declaringClass
                        );
                        return methodHandle.invoke(proxy);
                    }
                    throw new JSONException("This method '" + methodName + "' is not a getter");
                }
            } else {
                value = get(name);
                if (value == null) {
                    return null;
                }
            }

            if (!returnType.isInstance(value)) {
                Function typeConvert = JSONFactory
                        .getDefaultObjectReaderProvider()
                        .getTypeConvert(
                                value.getClass(), method.getGenericReturnType()
                        );

                if (typeConvert != null) {
                    value = typeConvert.apply(value);
                }
            }

            return value;
        }

        throw new UnsupportedOperationException(method.toGenericString());
    }
@param proxy proxy object, currently useless
@param method methods that need reflection
@param args parameters of invoke
@throws UnsupportedOperationException If reflection for this method is not supported
@throws ArrayIndexOutOfBoundsException If the length of args does not match the length of the method parameter
core/src/main/java/com/alibaba/fastjson2/JSONObject.java