I'm struggling to understand what I need to do to not loose type information when building a JavaBeanObjectProperty for generic type T. One interesting detail is that I don't get this warning from IntelliJ for the ReadOnlyJavaBeanObjectProperty.
public class FooWrapper<T> {
/**
* Decorates a Foo instance with javafx stuff
*/
private final Foo foo;
private final JavaBeanObjectProperty<T> value;
private final ReadOnlyJavaBeanObjectProperty<T> type;
public ParameterWrapper(Foo toWrap) {
this.foo = toWrap;
try {
this.value = new JavaBeanObjectPropertyBuilder<T>()
.bean(this.foo)
.name("value")
.build();
this.type = new ReadOnlyJavaBeanObjectPropertyBuilder<T>()
.bean(this.foo)
.name("type")
.build();
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
}
I have read Java unchecked operation cast to generic and Java Generics, how to avoid unchecked assignment warning when using class hierarchy? and am none the wiser.
The unchecked warnings are not your fault. The generic information is not kept because the API was poorly implemented. There is an unresolved issue regarding this: JDK-8152399. The issue is labeled as an "enhancement" but I'd consider it a bug.
The problem is caused by the fact nearly all the methods of JavaBeanObjectPropertyBuilder
return raw types. The only exception to this is build
which returns JavaBeanObjectProperty<T>
. This doesn't matter, however, because by the time you've called build
you've lost the type information from calling bean
and name
. Unfortunately, this means there's nothing you can do to legitimately get rid of the warning—you can only suppress it.
public class FooWrapper {
private final Foo delegate;
private final JavaBeanObjectProperty<SomeType> value;
@SuppressWarnings("unchecked") // Reason: Bad API
public FooWrapper(Foo delegate) {
this.delegate = delegate;
try {
value = JavaBeanObjectPropertyBuilder.create()
.bean(delegate)
.name("value")
.build();
} catch (NoSuchMethodException ex) {
throw new RuntimeException(ex);
}
}
}
This uses @SuppressWarnings
to suppress the unchecked warnings. You can read more about it here. It's good practice to apply @SuppressWarnings
to the narrowest scope possible so as to avoid suppressing other, useful warnings.
For comparison, look at the method signatures of ReadOnlyJavaBeanObjectPropertyBuilder
. They all return the generic type.