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