BeanFactory { public void bind(Type type, @Nullable String name, Object instance) { if (instance == null) throw new Error("instance must not be null"); if (!isTypeOf(instance, type)) throw new Error(format("instance type does not match, type={}, instanceType={}", type.getTypeName(), instance.getClass().getCanonicalName())); Object previous = beans.put(new Key(type, name), instance); if (previous != null) throw new Error(format("found duplicate bean, type={}, name={}, previous={}", type.getTypeName(), name, previous)); }  void bind(Type type, @Nullable String name, Object instance); Object bean(Type type, String name); T create(Class<T> instanceClass); void inject(T instance);  }
@Test void bindWithMismatchedType() { assertThatThrownBy(() -> beanFactory.bind(List.class, null, "instance")) .isInstanceOf(Error.class) .hasMessageContaining("instance type does not match"); }
@Test void bindGeneric() { beanFactory.bind(Types.list(String.class), null, new ArrayList<String>()); beanFactory.bind(Types.supplier(String.class), null, (Supplier<String>) () -> null); }