public static Type[] getReturnTypes(Invocation invocation) {
        try {
            if (invocation != null
                    && invocation.getInvoker() != null
                    && invocation.getInvoker().getUrl() != null
                    && invocation.getInvoker().getInterface() != GenericService.class
                    && !invocation.getMethodName().startsWith("$")) {
                Type[] returnTypes = null;
                if (invocation instanceof RpcInvocation) {
                    returnTypes = ((RpcInvocation) invocation).getReturnTypes();
                    if (returnTypes != null) {
                        return returnTypes;
                    }
                }
                String service = invocation.getInvoker().getUrl().getServiceInterface();
                if (StringUtils.isNotEmpty(service)) {
                    Method method = getMethodByService(invocation, service);
                    if (method != null) {
                        returnTypes = ReflectUtils.getReturnTypes(method);
                    }
                }
                if (returnTypes != null) {
                    return returnTypes;
                }
            }
        } catch (Throwable t) {
            logger.warn(COMMON_REFLECTIVE_OPERATION_FAILED, "", "", t.getMessage(), t);
        }
        return null;
    }
@Test
    void testGetReturnTypesUseCache() throws Exception {
        Class<?> demoServiceClass = DemoService.class;
        String serviceName = demoServiceClass.getName();
        Invoker invoker = createMockInvoker(
                URL.valueOf(
                        "test://127.0.0.1:1/org.apache.dubbo.rpc.support.DemoService?interface=org.apache.dubbo.rpc.support.DemoService"));

        RpcInvocation inv = new RpcInvocation(
                "testReturnType", serviceName, "", new Class<?>[] {String.class}, null, null, invoker, null);
        Type[] types = RpcUtils.getReturnTypes(inv);
        Assertions.assertNotNull(types);
        Assertions.assertEquals(2, types.length);
        Assertions.assertEquals(String.class, types[0]);
        Assertions.assertEquals(String.class, types[1]);
        Assertions.assertArrayEquals(types, inv.getReturnTypes());

        RpcInvocation inv1 = new RpcInvocation(
                "testReturnType1", serviceName, "", new Class<?>[] {String.class}, null, null, invoker, null);
        java.lang.reflect.Type[] types1 = RpcUtils.getReturnTypes(inv1);
        Assertions.assertNotNull(types1);
        Assertions.assertEquals(2, types1.length);
        Assertions.assertEquals(List.class, types1[0]);
        Assertions.assertEquals(
                demoServiceClass.getMethod("testReturnType1", String.class).getGenericReturnType(), types1[1]);
        Assertions.assertArrayEquals(types1, inv1.getReturnTypes());

        RpcInvocation inv2 = new RpcInvocation(
                "testReturnType2", serviceName, "", new Class<?>[] {String.class}, null, null, invoker, null);
        java.lang.reflect.Type[] types2 = RpcUtils.getReturnTypes(inv2);
        Assertions.assertNotNull(types2);
        Assertions.assertEquals(2, types2.length);
        Assertions.assertEquals(String.class, types2[0]);
        Assertions.assertEquals(String.class, types2[1]);
        Assertions.assertArrayEquals(types2, inv2.getReturnTypes());

        RpcInvocation inv3 = new RpcInvocation(
                "testReturnType3", serviceName, "", new Class<?>[] {String.class}, null, null, invoker, null);
        java.lang.reflect.Type[] types3 = RpcUtils.getReturnTypes(inv3);
        Assertions.assertNotNull(types3);
        Assertions.assertEquals(2, types3.length);
        Assertions.assertEquals(List.class, types3[0]);
        java.lang.reflect.Type genericReturnType3 =
                demoServiceClass.getMethod("testReturnType3", String.class).getGenericReturnType();
        Assertions.assertEquals(((ParameterizedType) genericReturnType3).getActualTypeArguments()[0], types3[1]);
        Assertions.assertArrayEquals(types3, inv3.getReturnTypes());

        RpcInvocation inv4 = new RpcInvocation(
                "testReturnType4", serviceName, "", new Class<?>[] {String.class}, null, null, invoker, null);
        java.lang.reflect.Type[] types4 = RpcUtils.getReturnTypes(inv4);
        Assertions.assertNotNull(types4);
        Assertions.assertEquals(2, types4.length);
        Assertions.assertNull(types4[0]);
        Assertions.assertNull(types4[1]);
        Assertions.assertArrayEquals(types4, inv4.getReturnTypes());

        RpcInvocation inv5 = new RpcInvocation(
                "testReturnType5", serviceName, "", new Class<?>[] {String.class}, null, null, invoker, null);
        java.lang.reflect.Type[] types5 = RpcUtils.getReturnTypes(inv5);
        Assertions.assertNotNull(types5);
        Assertions.assertEquals(2, types5.length);
        Assertions.assertEquals(Map.class, types5[0]);
        java.lang.reflect.Type genericReturnType5 =
                demoServiceClass.getMethod("testReturnType5", String.class).getGenericReturnType();
        Assertions.assertEquals(((ParameterizedType) genericReturnType5).getActualTypeArguments()[0], types5[1]);
        Assertions.assertArrayEquals(types5, inv5.getReturnTypes());
    }