PropertyConfigurationImpl implements PropertyConfiguration<C, P> { @Override @SuppressWarnings("unchecked") public PropertyConfiguration<C, P> onChange(SerializableBiConsumer<C, P> onChangeHandler) { Objects.requireNonNull(onChangeHandler, "Parameter 'onChangeHandler' " + "cannot be null!"); if (this.onChangeHandler != null) { throw new IllegalStateException(String.format("onChangeHandler " + "for property %s has already been set and cannot be " + "overwritten!", data.getName())); } this.onChangeHandler = (c, o) -> onChangeHandler.accept(c, (P) o); return this; } PropertyConfigurationImpl(Class<C> componentType, String propertyName,
                                     Class<P> propertyType, P defaultValue); @Override @SuppressWarnings("unchecked") PropertyConfiguration<C, P> onChange(SerializableBiConsumer<C, P> onChangeHandler); @Override PropertyConfiguration<C, P> readOnly(); @Override boolean equals(Object obj); @Override int hashCode(); SerializableBiConsumer<C, Serializable> getOnChangeHandler(); PropertyData<P> getPropertyData();  }
@Test public void onChange() { intPropertyConf.onChange(MyComponent::setInt); MyComponent myComponent = new MyComponent(); intPropertyConf.getOnChangeHandler().accept(myComponent, 5); Assert.assertEquals("onChangeHandler should have been set and value " + "updated", 5, myComponent.value); }
@Test(expected = IllegalStateException.class) public void onChange_throwsIfCalledTwice() { intPropertyConf.onChange(MyComponent::setInt); intPropertyConf.onChange(MyComponent::setInt); }