java 17 Preview 增加了 switch的模式匹配,遇到的两个问题

1. instanceof

  • java 16 对 instanceof 进行了增强,有时候可以不用
        //定义一个数组
        Object[] arr = {"1"};

        if (arr[0] instanceof String a) {
            //假如我们只想判断值为String,取 String.class,那还是别定义 a 变量了。
            System.out.println("相同的取值:" + String.class + ",a的class:" + a.getClass());
            System.out.println(a);
        }

		//是不是 这样更简便呢?
        if (arr[0] instanceof String) {
            //String.class 是我们想要的
            System.out.println(String.class);
        }

2. switch,遇到两个问题

  • java 17 Preview 增加了 switch的模式匹配,代码减少很多。
  • 问题1:我并不用变量a,我还必须定义它,改怎么写呢?

        Object[] arr = {"1"};

        switch (arr[0]) {
            case String a -> System.out.println("第一个分支:" + String.class + "值为:" + a);
            default -> System.out.println("默认:" + arr[0].getClass());
        }

		//但是呢,我并不用变量a,我还必须定义它,否则会报错
  • 问题2:如下代码,我该怎么优化呢?
        Object[] arr = {new ArrayList<>()};
        
        switch (arr[0]) {

            case ArrayList a -> System.out.println("第二个分支:" + List.class);
            case LinkedList a -> System.out.println("第二个分支:" + List.class);

            default -> System.out.println("默认:" + arr[0].getClass());
        }

3. 优化之后的两种方法

  • 优化了之后,感觉 很 K猪
    public static Class<?>[] getClazzByArgsForJava16(Object[] args) {

        Class<?>[] parameterTypes = new Class[args.length];

        for (int i = 0; i < args.length; i++) {

            if (args[i] instanceof String a) {
                parameterTypes[i] = String.class;
                continue;
            }
            //省略
        }
        return parameterTypes;
    }


    public static <x> Class<?>[] getClazzByArgsForJava17Preview(Object[] args) {

        Class<?>[] parameterTypes = new Class[args.length];
        
        for (int i = 0; i < args.length; i++) {

            switch (args[i]) {

                case ArrayList a -> parameterTypes[i] = List.class;
                case LinkedList a -> {
                    parameterTypes[i] = List.class;
                }
                case HashMap a -> parameterTypes[i] = Map.class;
                case Long a -> parameterTypes[i] = long.class;
                case Double a -> parameterTypes[i] = double.class;
                case TimeUnit a -> parameterTypes[i] = TimeUnit.class;

                default -> parameterTypes[i] = args[i].getClass();
            }
        }
        return parameterTypes;
    }

4. 原方法:

    public static Class<?>[] getClazzByArgs(Object[] args) {
        Class<?>[] parameterTypes = new Class[args.length];
        for (int i = 0; i < args.length; i++) {
            if (args[i] instanceof ArrayList) {
                parameterTypes[i] = List.class;
                continue;
            }
            if (args[i] instanceof LinkedList) {
                parameterTypes[i] = List.class;
                continue;
            }
            if (args[i] instanceof HashMap) {
                parameterTypes[i] = Map.class;
                continue;
            }
            if (args[i] instanceof Long) {
                parameterTypes[i] = long.class;
                continue;
            }
            if (args[i] instanceof Double) {
                parameterTypes[i] = double.class;
                continue;
            }
            if (args[i] instanceof TimeUnit) {
                parameterTypes[i] = TimeUnit.class;
                continue;
            }
            parameterTypes[i] = args[i].getClass();
        }
        return parameterTypes;
    }

  • 原方法使用场景,想使用一个 JDK代理的时候
代理的工厂
 public class JDKProxyFactory {

    //cacheAdapter 是我们要代理的忌口
    public static <T> T getProxy(Class<T> cacheClazz, Class<? extends ICacheAdapter> cacheAdapter) throws Exception {

        //cacheAdapter.newInstance() 方法已经弃用,按照说明用了新的newInstance方法
        InvocationHandler handler = new JDKInvocationHandler(cacheAdapter.getDeclaredConstructor().newInstance());

        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

        return (T) Proxy.newProxyInstance(classLoader, new Class[]{cacheClazz}, handler);
    }

}
InvocationHandler 的一个实现
  • 因为 代理 需要
public class JDKInvocationHandler implements InvocationHandler {

    private ICacheAdapter cacheAdapter;

    public JDKInvocationHandler(ICacheAdapter cacheAdapter) {
        this.cacheAdapter = cacheAdapter;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return ICacheAdapter.class.getMethod(
            method.getName(),
                ClassLoaderUtils.getClazzByArgs(args))
                .invoke(cacheAdapter, args);
    }

}
  • 如:.class.getMethod 方法,需要 方法名 和 参数类型的 Class<?>[] 数组,所以使用了 此工具类。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值