package com.shrimpking.t5;


import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import java.util.ArrayList;
import java.util.Arrays;

/**
 * Created by IntelliJ IDEA.
 *
 * @Author : Shrimpking
 * @create 2024/9/12 16:16
 */
interface Functor<T>{
    void call(T args);
}

class MyCallBack implements Functor<Object>{

    @Override
    public void call(Object args)
    {
        System.out.println(args);
    }
}

class CallbackTest{
    public static <T> T callback(ArrayList<T> list,Functor<? super T> func){
        for (T t : list)
        {
            func.call(t);
        }
        return list.get(0);
    }

}

public class GenericInfo
{
    public static void main(String[] args)
    {
        System.out.println("[MyCallback类的泛型信息]");

        Class clz = MyCallBack.class;
        Type baseType = clz.getGenericSuperclass();
        System.out.println("父类:");
        System.out.println(baseType);

        System.out.println("实现的接口:");
        Type[] interfaces = clz.getGenericInterfaces();
        for (Type t : interfaces)
        {
            System.out.println(t);
            //如果接口是参数化类型的
            if(t instanceof ParameterizedType){
                ParameterizedType pt = (ParameterizedType)t;
                //获取实际的参数
                Type[] typeArgs = pt.getActualTypeArguments();
                for (Type arg : typeArgs)
                {
                    System.out.println("--实际参数:" + arg);
                }
            }
        }

        System.out.println("----");

        System.out.println("[CallbackTest类中的泛型方法的泛型信息]");
        Class clazz = CallbackTest.class;
        Method[] methods = clazz.getMethods();
        System.out.println("方法的参数类型:");
        Type[] paramTypes = methods[0].getGenericParameterTypes();
        for (Type t : paramTypes)
        {
            System.out.println(t);
            //如果形参是参数化类型的
            if(t instanceof ParameterizedType){
                ParameterizedType pt = (ParameterizedType)t;
                //获取实际参数
                Type[] typeArgs = pt.getActualTypeArguments();
                for (Type arg : typeArgs)
                {
                    System.out.println("---实际的参数类型:" + arg);
                    //如果是通配符类型的
                    if(arg instanceof WildcardType){
                        WildcardType wt = (WildcardType)arg;
                        //输出变量的下限
                        System.out.println("--" + Arrays.toString(wt.getLowerBounds()));
                        //输出变量的上限
                        System.out.println("--" + Arrays.toString(wt.getUpperBounds()));
                    }
                }
            }
        }

        System.out.println("方法的返回类型:");
        Type returnType = methods[0].getGenericReturnType();
        System.out.println(returnType);
    }
}