提问java 17 Preview,switch,不用变量 和 分支代码一样怎么办?

1,如下所示:第一个分支,a的值,我不用,怎么不定义?

2,下面两个分支,代码一样,怎么合并?

Object[] arr = {"1"};

        switch (arr[0]) {
            case String a -> System.out.println("第一个分支:" + String.class);

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

}


 // instanceof 挺好,如果不用a,可以不定义
 if (arr[0] instanceof String a) {}
 if (arr[0] instanceof String ) {}

 

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<?>[] 数组,所以使用了 此工具类。

 

请登录后发表评论