From 4038be5e42b54bd096c6b6c3fc20c4e40898f98a Mon Sep 17 00:00:00 2001 From: Julian Vassev Date: Thu, 2 Nov 2017 19:14:37 +0200 Subject: [PATCH] Replace switch with reflection in generated code This patch expands on the suggestion in https://github.com/ben-manes/caffeine/issues/110#issuecomment-238676087 Instead of the proposed numeric code the name of factory is used as the classname to instantiate using reflection. This reduces the class size with 21K bringing the jar size to 786K. --- .../cache/LocalCacheSelectorCode.java | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/caffeine/src/javaPoet/java/com/github/benmanes/caffeine/cache/LocalCacheSelectorCode.java b/caffeine/src/javaPoet/java/com/github/benmanes/caffeine/cache/LocalCacheSelectorCode.java index 2318cc9a4a..15a3e37049 100644 --- a/caffeine/src/javaPoet/java/com/github/benmanes/caffeine/cache/LocalCacheSelectorCode.java +++ b/caffeine/src/javaPoet/java/com/github/benmanes/caffeine/cache/LocalCacheSelectorCode.java @@ -15,6 +15,7 @@ */ package com.github.benmanes.caffeine.cache; +import java.lang.reflect.Constructor; import java.util.Set; import com.squareup.javapoet.CodeBlock; @@ -88,16 +89,18 @@ private LocalCacheSelectorCode expires() { return this; } - private LocalCacheSelectorCode selector(Set classNames) { - CodeBlock.Builder switchBuilder = CodeBlock.builder(); - switchBuilder.beginControlFlow("switch (sb.toString())"); - for (String className : classNames) { - switchBuilder.addStatement( - "case $S: return new $N<>(builder, cacheLoader, async)", className, className); - } - switchBuilder.addStatement("default: throw new $T(sb.toString())", IllegalStateException.class); - switchBuilder.endControlFlow(); - block.add(switchBuilder.build()); + private LocalCacheSelectorCode selector() { + CodeBlock.Builder reflectBuilder = CodeBlock.builder(); + reflectBuilder.add("try {\n" + + " Class cls = LocalCacheFactory.class.getClassLoader()\n" + + " .loadClass(\"com.github.benmanes.caffeine.cache.LocalCacheFactory$$\" + sb.toString());\n" + + " $T ctor = cls.getDeclaredConstructor(Caffeine.class, CacheLoader.class, boolean.class);\n" + + " return (BoundedLocalCache) ctor.newInstance(builder, cacheLoader, async);\n" + + "} catch (ReflectiveOperationException e) {\n" + + " throw new IllegalStateException(sb.toString());\n" + + "}\n" + + "\n", Constructor.class); + block.add(reflectBuilder.build()); return this; } @@ -113,7 +116,7 @@ public static CodeBlock get(Set classNames) { .stats() .maximum() .expires() - .selector(classNames) + .selector() .build(); } }