diff --git a/pom.xml b/pom.xml
index 658ddbe..eea9ba3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,6 +24,11 @@
asm-tree
9.4
+
+ org.openjdk.jol
+ jol-core
+ 0.17
+
diff --git a/src/main/java/com/github/shautvast/reflective/array/ArrayCreator.java b/src/main/java/com/github/shautvast/reflective/array/ArrayCreator.java
new file mode 100644
index 0000000..54d62b6
--- /dev/null
+++ b/src/main/java/com/github/shautvast/reflective/array/ArrayCreator.java
@@ -0,0 +1,6 @@
+package com.github.shautvast.reflective.array;
+
+public abstract class ArrayCreator {
+
+ public abstract Object newInstance();
+}
diff --git a/src/main/java/com/github/shautvast/reflective/array/ArrayFactory.java b/src/main/java/com/github/shautvast/reflective/array/ArrayFactory.java
new file mode 100644
index 0000000..0e4fb46
--- /dev/null
+++ b/src/main/java/com/github/shautvast/reflective/array/ArrayFactory.java
@@ -0,0 +1,75 @@
+package com.github.shautvast.reflective.array;
+
+import com.github.shautvast.reflective.java.ASM;
+import com.github.shautvast.reflective.java.ByteClassLoader;
+import com.github.shautvast.reflective.java.Java;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.tree.*;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import static org.objectweb.asm.Opcodes.*;
+
+public class ArrayFactory {
+
+ /*
+ should become
+ public static T newArray(Class componentType)
+ or
+ public static T newArray(Class componentType, int... dimensions)
+ */
+ public static Object newArray(Class> componentType, int... dimensions) {
+ return newArray(componentType.getName(), dimensions);
+ }
+
+ public static Object newArray(String componentType, int... dimensions) {
+ ClassNode classNode = ASM.createDefaultClassNode(
+ "ReflectiveCreator" + dimensions.length,
+ Java.internalName(ArrayCreator.class));
+ MethodNode methodNode = new MethodNode(ACC_PUBLIC,
+ "newInstance", "()Ljava/lang/Object;", null, null);
+ classNode.methods.add(methodNode);
+ InsnList insns = methodNode.instructions;
+
+ int localVarIndex = 0;
+ StringBuilder arrayType = new StringBuilder(dimensions.length);
+ String post = "";
+ String pre = "";
+ insns.add(new LdcInsnNode(1));
+ insns.add(new LdcInsnNode(1));
+ insns.add(new LdcInsnNode(1));
+ insns.add(new MultiANewArrayInsnNode("[[[Ljava/lang/String;",3));
+
+// for (int dim : dimensions) {
+// insns.add(new LdcInsnNode(dim));
+// String type = arrayType + pre + Java.internalName(componentType) + post;
+// insns.add(new TypeInsnNode(ANEWARRAY, type));
+// insns.add(new VarInsnNode(ASTORE, ++localVarIndex));
+// arrayType.append("[");
+// pre = "L";
+// post = ";";
+//
+// }
+
+// insns.add(new VarInsnNode(ALOAD, localVarIndex));
+ insns.add(new InsnNode(ARETURN));
+ ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+ classNode.accept(classWriter);
+ byte[] byteArray = classWriter.toByteArray();
+
+ try (FileOutputStream out = new FileOutputStream("A.class")) {
+ out.write(byteArray);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ // load it into the JVM
+ ByteClassLoader.INSTANCE.addClass(classNode.name, byteArray);
+ try {
+ return ((ArrayCreator) ByteClassLoader.INSTANCE.loadClass(classNode.name).getConstructor().newInstance()).newInstance();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/src/main/java/com/github/shautvast/reflective/array/Arrays.java b/src/main/java/com/github/shautvast/reflective/array/Arrays.java
new file mode 100644
index 0000000..6060468
--- /dev/null
+++ b/src/main/java/com/github/shautvast/reflective/array/Arrays.java
@@ -0,0 +1,17 @@
+package com.github.shautvast.reflective.array;
+
+public class Arrays {
+ private Arrays() {
+ }
+
+ public static Object newInstance(Class> componentType, int... dimensions)
+ throws IllegalArgumentException, NegativeArraySizeException {
+ return new String[dimensions[1]][2][3];
+ }
+
+ public static void main(String[] args) {
+ String[][][] a = (String[][][])newInstance(String.class, 1, 2, 3);
+ a[0]=new String[1][2];
+
+ }
+}
diff --git a/src/test/java/com/github/shautvast/reflective/ReflectiveTest.java b/src/test/java/com/github/shautvast/reflective/ReflectiveTest.java
index 534de92..0291d99 100644
--- a/src/test/java/com/github/shautvast/reflective/ReflectiveTest.java
+++ b/src/test/java/com/github/shautvast/reflective/ReflectiveTest.java
@@ -54,7 +54,9 @@ public class ReflectiveTest {
Dummy dummy = new Dummy("bar");
MetaMethod getName = Reflective.getMetaClass(dummy.getClass()).getMethod("getName").orElseGet(Assertions::fail);
+ // passing "foo" as the instance is not allowed
assertThrows(Panic.class, () -> getName.invoke("foo").unwrap());
+ // we should pass a valid dummy instance
assertEquals("bar", getName.invoke(dummy).unwrap());
}
diff --git a/src/test/java/com/github/shautvast/reflective/array/ArraysTest.java b/src/test/java/com/github/shautvast/reflective/array/ArraysTest.java
new file mode 100644
index 0000000..f9d8a03
--- /dev/null
+++ b/src/test/java/com/github/shautvast/reflective/array/ArraysTest.java
@@ -0,0 +1,51 @@
+package com.github.shautvast.reflective.array;
+
+import org.junit.jupiter.api.Test;
+
+import java.lang.reflect.Array;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class ArraysTest {
+
+
+ @Test
+ void test1Dim() {
+ Object o = ArrayFactory.newArray(String.class, 1);
+ assertTrue(o instanceof String[]);
+ }
+
+ @Test
+ void test2Dims() {
+ Object o = ArrayFactory.newArray(String.class, 1, 2);
+ assertTrue(o instanceof String[][]);
+ }
+
+ @Test
+ void test3Dims() {
+ String[][][] array = (String[][][]) ArrayFactory.newArray(String[][][].class, 1, 2, 3);
+ assertEquals(1, array.length);
+ array[0] = new String[2][1];
+ array[0][1] = new String[1];
+ }
+
+ @Test
+ void test3DimsT() {
+ String[][][] array = new String[1][1][1];
+ assertEquals(1, array.length);
+ array[0] = new String[2][1];
+
+ array[0][0] = new String[1];
+ array[0][1] = new String[1];
+ array[0][0][0]="0,0,0";
+ array[0][1][0]="0,1,0"; // WTF?
+ System.out.println(array[0][1][0]);
+ }
+
+ @Test
+ void forName() throws ClassNotFoundException {
+ Class.forName("[Ljava.lang.String;");
+ }
+
+}