From 224780a84dbae2fc1adf3d948bb2942adb1f9b54 Mon Sep 17 00:00:00 2001 From: Mark Vainomaa Date: Fri, 24 Feb 2017 15:45:00 +0200 Subject: [PATCH] Add method to construct classes using reflection --- .../eu/mikroskeem/utils/reflect/Reflect.java | 37 +++++++++++++++++++ .../test/reflect/DifferentConstructors.java | 6 +++ .../utils/test/reflect/TestReflect.java | 16 ++++++++ 3 files changed, 59 insertions(+) create mode 100644 Reflect/src/test/java/eu/mikroskeem/utils/test/reflect/DifferentConstructors.java diff --git a/Reflect/src/main/java/eu/mikroskeem/utils/reflect/Reflect.java b/Reflect/src/main/java/eu/mikroskeem/utils/reflect/Reflect.java index f941d1a..b84da86 100644 --- a/Reflect/src/main/java/eu/mikroskeem/utils/reflect/Reflect.java +++ b/Reflect/src/main/java/eu/mikroskeem/utils/reflect/Reflect.java @@ -1,11 +1,16 @@ package eu.mikroskeem.utils.reflect; +import lombok.Getter; +import lombok.RequiredArgsConstructor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.stream.Collectors; +import java.util.stream.Stream; /** * Reflection utils @@ -39,6 +44,27 @@ public class Reflect { return getClass(clazz) != null; } + /** + * Construct class with arguments. Note: primitive types aren't supported + * + * + * @param clazz Class to construct + * @param arguments Class constructor arguments + * @return Class instance or null + */ + public static Object fastConstruct(@NotNull Class clazz, TypeWrapper... arguments){ + try { + Class[] tArgs = Stream.of(arguments).map(TypeWrapper::getType).collect(Collectors.toList()).toArray(new Class[0]); + Object[] args = Stream.of(arguments).map(TypeWrapper::getValue).collect(Collectors.toList()).toArray(); + Constructor constructor = clazz.getDeclaredConstructor(tArgs); + constructor.setAccessible(true); + return constructor.newInstance(args); + } catch (NoSuchMethodException|InstantiationException|IllegalAccessException|InvocationTargetException e){ + e.printStackTrace(); + return null; + } + } + /** * Get declared class method (public,protected,private) * @@ -188,4 +214,15 @@ public class Reflect { } return null; } + + + /** + * Type/value wrapper for reflective constructing + */ + @RequiredArgsConstructor + @Getter + public static class TypeWrapper { + private final Object value; + private final Class type; + } } diff --git a/Reflect/src/test/java/eu/mikroskeem/utils/test/reflect/DifferentConstructors.java b/Reflect/src/test/java/eu/mikroskeem/utils/test/reflect/DifferentConstructors.java new file mode 100644 index 0000000..1ed9a0a --- /dev/null +++ b/Reflect/src/test/java/eu/mikroskeem/utils/test/reflect/DifferentConstructors.java @@ -0,0 +1,6 @@ +package eu.mikroskeem.utils.test.reflect; + +public class DifferentConstructors { + public DifferentConstructors(Integer a, Integer b, int c, boolean d){} + private DifferentConstructors(String foo, String bar){} +} diff --git a/Reflect/src/test/java/eu/mikroskeem/utils/test/reflect/TestReflect.java b/Reflect/src/test/java/eu/mikroskeem/utils/test/reflect/TestReflect.java index 8fc327a..133a76c 100644 --- a/Reflect/src/test/java/eu/mikroskeem/utils/test/reflect/TestReflect.java +++ b/Reflect/src/test/java/eu/mikroskeem/utils/test/reflect/TestReflect.java @@ -112,4 +112,20 @@ public class TestReflect { Assert.assertTrue(Reflect.classExists(className)); Assert.assertEquals("hey", testFieldContent); } + + @Test + public void testConstructing(){ + Assert.assertNotNull(Reflect.fastConstruct( + DifferentConstructors.class, + new Reflect.TypeWrapper(1, Integer.class), + new Reflect.TypeWrapper(2, Integer.class), + new Reflect.TypeWrapper(3, int.class), + new Reflect.TypeWrapper(true, boolean.class) + )); + Assert.assertNotNull(Reflect.fastConstruct( + DifferentConstructors.class, + new Reflect.TypeWrapper("kek", String.class), + new Reflect.TypeWrapper("kek", String.class) + )); + } }