Mastering Java Hidden Classes: A Step-by-Step Guide with Code
This article explains Java hidden classes—runtime‑generated, reflection‑only classes—through a clear example that creates a simple class, encodes it, loads it as a hidden class, and invokes its method, demonstrating a powerful dynamic feature for frameworks.
What are Hidden Classes
Hidden classes are classes that cannot be accessed directly by other classes; they are intended for frameworks to generate and use at runtime via reflection.
Hidden Class Example
Step 1: Create a normal Java class.
public class JEP371HiddenClasses {
public static String hello() {
return "https://www.didispace.com";
}
}Step 2: Compile the class, read the .class file and encode it with Base64.
String filePath = "JEP371HiddenClasses.class";
byte[] b = Files.readAllBytes(Paths.get(filePath));
log.info(Base64.getEncoder().encodeToString(b));The resulting Base64 string represents the compiled class.
Step 3: Load the hidden class via MethodHandles.defineHiddenClass and invoke its hello method.
@Test
void testHiddenClasses() throws Throwable {
// 1. Load the encoded hidden class
String CLASS_INFO = "yv66vgAAAD0AFAoAAgADBwAEDAAFAAYBABBqYXZhL2xhbmcvT2JqZWN0AQAGPGluaXQ+AQADKClWCAAIAQAZaHR0cHM6Ly93d3cuZGlkaXNwYWNlLmNvbQcACgEALmNvbS9kaWRpc3BhY2UvZGVidWcvamF2YTE1L0pFUDM3MUhpZGRlbkNsYXNzZXMBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAMExjb20vZGlkaXNwYWNlL2RlYnVnL2phdmExNS9KRVAzNzFIaWRkZW5DbGFzc2VzOwEABWhlbGxvAQAUKClMamF2YS9sYW5nL1N0cmluZzsBAApTb3VyY2VGaWxlAQAYSkVQMzcxSGlkZGVuQ2xhc3Nlcy5qYXZhACEACQACAAAAAAACAAEABQAGAAEACwAAAC8AAQABAAAABSq3AAGxAAAAAgAMAAAABgABAAAAAwANAAAADAABAAAABQAOAA8AAAAJABAAEQABAAsAAAAbAAEAAAAAAAMSB7AAAAABAAwAAAAGAAEAAAAGAAEAEgAAAAIAEw==";
byte[] classInBytes = getDecoder().decode(CLASS_INFO);
Class<?> proxy = MethodHandles.lookup()
.defineHiddenClass(classInBytes, true, MethodHandles.Lookup.ClassOption.NESTMATE)
.lookupClass();
// Output class name and methods
log.info(proxy.getName());
for (Method method : proxy.getDeclaredMethods()) {
log.info(method.getName());
}
// 2. Invoke hello()
MethodHandle mh = MethodHandles.lookup().findStatic(proxy, "hello",
MethodType.methodType(String.class));
String result = (String) mh.invokeExact();
log.info(result);
}Running the test prints the hidden class name, its method name, and the string returned by hello():
17:20:50.360 [main] INFO com.didispace.debug.java15.JEP371Test - com.didispace.debug.java15.JEP371HiddenClasses/0x0000000800cb0c00
17:20:50.361 [main] INFO com.didispace.debug.java15.JEP371Test - hello
17:20:50.361 [main] INFO com.didispace.debug.java15.JEP371Test - https://www.didispace.comThis demonstrates how hidden classes provide an additional dynamic capability for framework developers.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
