I'm working with a TreeTable
and when changing cell factory I am required to pass a
Callback<TreeTableColumn<A, capture of ?>, TreeTableCell<A, capture of ?>>
where A is a class I am working with but I have no idea how to work with the "capture of ?"
I tried to create
new Callback<TreeTableColumn<A, ?>, TreeTableCell<A, ?>>
but IDEA shows warning
setCellFactory(Callback<TreeTableColumn<A, capture<?>>, TreeTableCell<A, capture<?>>>) in TreeTableColumn cannot be applied to (anonymous Callback<TreeTableColumn<A, ?>, TreeTableCell<A, ?>>)
I tried using specific classes (like String) instead of "?" as well, but nothing helped.
Could anyone explain to me how to work with this?
Thank you.
EDIT:
I gathered a little bit more information.. the CellFactory
of TreeTableColumn<S,T>
should be Callback<TreeTableColumn<S,T>
,TreeTableCell<S,T>>
, however, the TreeTableColumn that I'm working with is created as a raw type (in a library).
Using a raw type Callback works. But are there any other options how to work this around?
wildcard capture is the process of binding the value of a wildcard type to a new type variable. For example: List<?> list = ...; shuffle(list); where <T> void shuffle(List<T> list) { ...
In some cases, the compiler infers the type of a wildcard. For example, a list may be defined as List<?> but, when evaluating an expression, the compiler infers a particular type from the code. This scenario is known as wildcard capture.
Generics add that type of safety feature. We will discuss that type of safety feature in later examples. Generics in Java are similar to templates in C++. For example, classes like HashSet, ArrayList, HashMap, etc., use generics very well.
In generic code, the question mark (?), called the wildcard, represents an unknown type. The wildcard can be used in a variety of situations: as the type of a parameter, field, or local variable; sometimes as a return type (though it is better programming practice to be more specific).
A wildcard represents an unknown type.
wildcard capture is the process of binding the value of a wildcard type to a new type variable. For example:
List<?> list = ...; shuffle(list);
where
<T> void shuffle(List<T> list) { ... }
Here, the unknown value of ?
is bound to the new type variable T
upon invocation of the shuffle
method, allowing the shuffle method to refer to that type.
The Java compiler internally represents the value of a wildcard by capturing it in an anonymous type variable, which it calls "capture of ?" (actually, javac calls them "capture #1 of ?" because different uses of ?
may refer to different types, and therefore have different captures).
Ok, so what is wrong in your code? You are trying to invoke a method
<S,T> setCellFactory(Callback<TreeTableColumn<S,T>, TreeTableCell<S,T>> factory);
with
Callback<TreeTableColumn<S,?>, TreeTableCell<S, ?>> factory;
In the method signature, the type parameter T stands for a single type, that must be provided by the caller. As a convenience, the compiler automatically attempts to infer a suitable value (-> type inference). Your compilation error means that the compiler was unable to do so.
In this instance, this is not a shortcoming of type inference, as it is actually impossible to assign a suitable value to T
, because both ?
need to be subtypes of T
, but the compiler can not know that the two ?
stand for the same type, or even related types.
To successfully invoke this method, your argument type must use the same type for all occurrences of T. If you already have such a type at hand, go ahead and use it. Otherwise, you may be able to introduce one using wildcard capture:
setCellFactory(newFactory());
where
<S,T> Callback<TreeTableColumn<S,T>, TreeTableCell<S,T>> newFactory() { return new Callback<TreeTableColumn<S,T>, TreeTableCell<S,T>> { ... } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With