Google guava Lists类的newArrayList方法遇坑记录

程序员就是不断的踩坑脱坑,人生又何尝不是这样呢?
这段代码的初衷是想通过一个入口传入的类型不同通过反射去调用可能位于不同service下的不同方法,当然可能返回值也不同。

@Service
@Slf4j
public class WorkOrderDispatchService {

    @Resource
    private Reflections reflections;

    public Object dispatch(Integer type,String cowShed){
        try{
            //扫描service下所有被@WorkOrderDispatch注解的方法
            Set<Method> methods = reflections.getMethodsAnnotatedWith(WorkOrderDispatch.class);
            //定位方法上@WorkOrderDispatch的type字段int[]包含传入的type的方法
            Method method = methods.stream().filter(m -> Lists.newArrayList(m.getAnnotation(WorkOrderDispatch.class).type()).contains(type) ).findFirst().get();
            //获取将被调用的方法的Class对象
            Class clazz = method.getDeclaringClass();
            //通过Class找到对应的service
            Object service = ApplicationContextUtil.getBean(clazz);
            Object result = method.invoke(service,type,cowShed);
            return result;
        }catch (Exception e){
            log.error("派单出错...",e);
            return null;
        }
    }

}
@Retention(RetentionPolicy.RUNTIME)
@Target(value = ElementType.METHOD)
@Documented
public @interface WorkOrderDispatch {
    int[] type();
}
@WorkOrderDispatch(type = {2,8})
public void test(Integer type,String cowShed){
    System.out.println("测试方法");
}

以前使用Lists.newArrayList()别的不是基础类型的时候,比如:
Student[] students的一个数组使用该方法得到的是一个List<Student>的对象,这次因为使用注解,而注解里的元素不允许是Integer[]数组。导致传入一个int[]数组调用List.newArrayList(int[])得到的是List<int[]>这样的类型,所以匹配不到,调用不了我的test方法。debug了一下,自动转换成了二维数组,int[]被看成是一个E的对象了。


图1

如果可变参数定义成基本类型,也是可以的


图2

最后改成Integer[]类型的数组解决问题

public Object dispatch(Integer type, String cowShed) {
        try {
            //扫描service下所有被@WorkOrderDispatch注解的方法
            Set<Method> methods = reflections.getMethodsAnnotatedWith(WorkOrderDispatch.class);
            //获取WorkOrderDispatch注解包含该type的方法,不要多个方法有同一个type
            Method method = methods.stream().filter(m -> Lists.newArrayList(Arrays.stream(m.getAnnotation(WorkOrderDispatch.class).type())
                    .boxed().toArray(Integer[]::new)).contains(type)).findFirst().get();
            //获取将被调用的方法的Class对象
            Class clazz = method.getDeclaringClass();
            //通过Class找到对应的service
            Object service = ApplicationContextUtil.getBean(clazz);
            //反射调用该方法
            Object result = method.invoke(service, type, cowShed);
            return result;
        } catch (Exception e) {
            log.error("派单出错...", e);
            return null;
        }
    }

这里总结一下注解元素允许的类型:

  1. 基本类型 byte short int long float double char boolean
  2. String
  3. Class
  4. Enum
  5. Annotation
  6. 上面所有类型的数组
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容