FlexibleFactory { @SuppressWarnings("ConstantConditions") public static <T> T create(@NonNull Class<T> itemClass, @Nullable Object... constructorParams) { if (itemClass == null) { throw new IllegalArgumentException("Unknown model class " + itemClass); } try { if (constructorParams == null || constructorParams.length == 0) { return itemClass.getConstructor().newInstance(); } else { Class[] classes = new Class[constructorParams.length]; for (int i = 0; i < constructorParams.length; i++) { classes[i] = constructorParams[i].getClass(); } return itemClass.getConstructor(classes).newInstance(constructorParams); } } catch (NoSuchMethodException e) { throw new RuntimeException(e.getMessage() + " " + itemClass.getCanonicalName() + ".<init>() has mismatching Constructor param"); } catch (Exception e) { throw new RuntimeException(e); } } private  FlexibleFactory(); @SuppressWarnings("ConstantConditions") static T create(@NonNull Class<T> itemClass, @Nullable Object... constructorParams);  }
@Test public void createHeaderHolder() { HeaderModel header = new HeaderModel("H1"); HeaderHolder headerHolder = FlexibleFactory.create(HeaderHolder.class, header); assertNotNull(headerHolder); assertEquals(header, headerHolder.getModel()); }
@Test public void createItemHolder() { HeaderModel header = new HeaderModel("H1"); HeaderHolder headerHolder = FlexibleFactory.create(HeaderHolder.class, header); ItemModel item = new ItemModel("I1", "H2"); ItemHolder itemHolder = FlexibleFactory.create(ItemHolder.class, item, headerHolder); assertNotNull(itemHolder); assertEquals(item, itemHolder.getModel()); assertEquals(headerHolder, itemHolder.getHeader()); assertEquals(header, itemHolder.getHeader().getModel()); }
@Test public void createWithMismatchingParam() { assertThrows(RuntimeException.class, () -> { FlexibleFactory.create(HeaderHolder.class, new Object()); }); }