diff options
Diffstat (limited to 'tests/features197')
-rw-r--r-- | tests/features197/java15/Employee.java | 1 | ||||
-rw-r--r-- | tests/features197/java15/HiddenClass.java | 6 | ||||
-rw-r--r-- | tests/features197/java15/HiddenClassDemo.java | 39 | ||||
-rw-r--r-- | tests/features197/java15/Manager.java | 1 | ||||
-rw-r--r-- | tests/features197/java15/Person.java | 5 | ||||
-rw-r--r-- | tests/features197/java15/PersonAspect.aj | 17 | ||||
-rw-r--r-- | tests/features197/java15/PersonaNonGrata.java | 2 | ||||
-rw-r--r-- | tests/features197/java15/TopManager.java | 10 |
8 files changed, 81 insertions, 0 deletions
diff --git a/tests/features197/java15/Employee.java b/tests/features197/java15/Employee.java new file mode 100644 index 000000000..9b0b9da99 --- /dev/null +++ b/tests/features197/java15/Employee.java @@ -0,0 +1 @@ +public final class Employee extends Person {} diff --git a/tests/features197/java15/HiddenClass.java b/tests/features197/java15/HiddenClass.java new file mode 100644 index 000000000..f1ef61166 --- /dev/null +++ b/tests/features197/java15/HiddenClass.java @@ -0,0 +1,6 @@ +public class HiddenClass implements Test { + @Override + public void concat(String... words) { + System.out.println(String.join(" ", words)); + } +} diff --git a/tests/features197/java15/HiddenClassDemo.java b/tests/features197/java15/HiddenClassDemo.java new file mode 100644 index 000000000..0b7f0ab17 --- /dev/null +++ b/tests/features197/java15/HiddenClassDemo.java @@ -0,0 +1,39 @@ +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); +} diff --git a/tests/features197/java15/Manager.java b/tests/features197/java15/Manager.java new file mode 100644 index 000000000..09b897d1e --- /dev/null +++ b/tests/features197/java15/Manager.java @@ -0,0 +1 @@ +public non-sealed class Manager extends Person {} diff --git a/tests/features197/java15/Person.java b/tests/features197/java15/Person.java new file mode 100644 index 000000000..cdd87d7f3 --- /dev/null +++ b/tests/features197/java15/Person.java @@ -0,0 +1,5 @@ +public abstract sealed class Person permits Employee, Manager { + public void sayHello(String name) { + System.out.println("Hello " + name); + } +} diff --git a/tests/features197/java15/PersonAspect.aj b/tests/features197/java15/PersonAspect.aj new file mode 100644 index 000000000..695a4de36 --- /dev/null +++ b/tests/features197/java15/PersonAspect.aj @@ -0,0 +1,17 @@ +public aspect PersonAspect { + // Weave into sealed class + void around(String name): execution(void sayHello(*)) && args(name) { + proceed("Sir " + name); + } + + // ITD into non-sealed subclass of sealed class + private String Manager.jobTitle; + + public void TopManager.setJobTitle(String jobTitle) { + this.jobTitle = jobTitle; + } + + public String TopManager.getJobTitle() { + return jobTitle; + } +} diff --git a/tests/features197/java15/PersonaNonGrata.java b/tests/features197/java15/PersonaNonGrata.java new file mode 100644 index 000000000..fc801536d --- /dev/null +++ b/tests/features197/java15/PersonaNonGrata.java @@ -0,0 +1,2 @@ +// This should not compile because Person is sealed and does not allow PersonaNonGrata as a subclass +public final class PersonaNonGrata extends Person {} diff --git a/tests/features197/java15/TopManager.java b/tests/features197/java15/TopManager.java new file mode 100644 index 000000000..e1dfdc367 --- /dev/null +++ b/tests/features197/java15/TopManager.java @@ -0,0 +1,10 @@ +public class TopManager extends Manager { + public static void main(String[] args) { + TopManager topManager = new TopManager(); + topManager.sayHello("John"); + + // Call ITD methods + topManager.setJobTitle("CEO"); + System.out.println(topManager.getJobTitle()); + } +} |