123456789101112131415161718192021222324252627282930313233343536373839 |
- import java.lang.invoke.MethodHandles;
- import java.lang.reflect.Constructor;
-
- import java.io.FileInputStream;
-
- import static java.lang.invoke.MethodHandles.Lookup.ClassOption.NESTMATE;
-
- public class HiddenClassDemo {
- public static void main(String[] args) throws Throwable {
- // Step 1: Create lookup object
- MethodHandles.Lookup lookup = MethodHandles.lookup();
-
- // Step 2: Fetch or create the class bytes we want to define
- byte[] bytes = Thread.currentThread().getContextClassLoader()
- .getResourceAsStream("HiddenClass.class")
- .readAllBytes();
-
- // Step 3: Define hidden class
- Class<?> clazz = lookup.defineHiddenClass(bytes, true, NESTMATE).lookupClass();
- // Hidden classes have class names like my.package.MyClass/0x2a23f5, but no canonical name (null)
- System.out.println("Hidden class name = " + clazz.getName());
- System.out.println("Hidden class canonical name = " + clazz.getCanonicalName ());
- // Hidden classes cannot be resolved by any class loader (ClassNotFoundException)
- try {
- Class.forName(clazz.getName());
- }
- catch (ClassNotFoundException e) {
- System.out.println("Class.forName resolution error = " + e);
- }
-
- //Step 4: Create instance of hidden class object and call interface method
- Test test = (Test) clazz.getConstructor(null).newInstance(null);
- test.concat("Hello", "from", "dynamically", "defined", "hidden", "class");
- }
- }
-
- interface Test {
- void concat(String... words);
- }
|