Java泛型“捕获?”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40217285/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java generics "capture of ?"
提问by kotycheese
I'm working with a TreeTable
and when changing cell factory I am required to pass a
我正在使用一个TreeTable
,当改变细胞工厂时,我需要通过一个
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 ?"
其中 A 是我正在使用的类,但我不知道如何使用“捕获 ?”
I tried to create
我试图创造
new Callback<TreeTableColumn<A, ?>, TreeTableCell<A, ?>>
but IDEA shows warning
但 IDEA 显示警告
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.
我尝试使用特定的类(如 String)而不是“?” 同样,但没有任何帮助。
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).
我收集了更多信息.. CellFactory
ofTreeTableColumn<S,T>
应该是Callback<TreeTableColumn<S,T>
,TreeTableCell<S,T>>
但是,我正在使用的 TreeTableColumn 是作为原始类型创建的(在库中)。
Using a raw type Callback works. But are there any other options how to work this around?
使用原始类型回调有效。但是还有其他选择可以解决这个问题吗?
采纳答案by meriton
A wildcardrepresents an unknown type.
甲通配符表示一个未知类型。
wildcard captureis 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.
在这里,未知值在调用方法时?
绑定到新的类型变量,从而允许 shuffle 方法引用该类型。T
shuffle
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).
Java 编译器通过在匿名类型变量中捕获通配符来在内部表示通配符的值,它称之为“捕获?” (实际上,javac 称它们为“capture #1 of ?”,因为 的不同用法?
可能指的是不同的类型,因此有不同的捕获)。
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.
在方法签名中,类型参数 T 代表单一类型,必须由调用者提供。为方便起见,编译器会自动尝试推断合适的值(-> 类型推断)。您的编译错误意味着编译器无法这样做。
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.
在这种情况下,这不是类型推断的缺点,因为实际上不可能为 分配合适的值T
,因为两者都?
需要是 的子类型T
,但编译器无法知道这两者?
代表同一类型,甚至相关类型。
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:
要成功调用此方法,您的参数类型必须对所有出现的 T 使用相同的类型。如果您手头已有这样的类型,请继续使用它。否则,您可以使用通配符捕获来引入一个:
setCellFactory(newFactory());
where
在哪里
<S,T> Callback<TreeTableColumn<S,T>, TreeTableCell<S,T>> newFactory() {
return new Callback<TreeTableColumn<S,T>, TreeTableCell<S,T>> {
...
}
}
回答by Nico
from what I found from what is a capture conversionand oracle capture generic docsit looks like you are facing some problem where the compiler can't find the needed helper class, or tries to place Object in there, but what you give him can not be converted safely.
从我从 捕获转换和oracle 捕获通用文档中发现的内容来看,您似乎面临一些问题,编译器找不到所需的帮助程序类,或者尝试将 Object 放在那里,但是您给他的却不能安全转换。
EDIT:
编辑:
DEFAULT_CELL_FACTORY
public static final Callback<TreeTableColumn<?,?>,TreeTableCell<?,?>>
If no cellFactory is specified on a TreeTableColumn instance, then this one will be used by default. At present it simply renders the TableCell item property within the graphic property if the item is a Node, or it simply calls toString() if it is not null, setting the resulting string inside the text property.
DEFAULT_CELL_FACTORY
public static final Callback<TreeTableColumn<?,?>,TreeTableCell<?,?>>
如果未在 TreeTableColumn 实例上指定 cellFactory,则默认情况下将使用该实例。目前,如果项目是一个节点,它只是在图形属性中呈现 TableCell 项目属性,或者如果它不为空,它就简单地调用 toString(),在文本属性中设置结果字符串。
and
和
setCellFactory
public final void setCellFactory(Callback<TreeTableColumn<S,T>,TreeTableCell<S,T>> value)
Sets the value of the property cellFactory. Property description: The cell factory for all cells in this column. The cell factory is responsible for rendering the data contained within each TreeTableCell for a single TreeTableColumn. By default TreeTableColumn uses a default cell factory, but this can be replaced with a custom implementation, for example to show data in a different way or to support editing. There is a lot of documentation on creating custom cell factories elsewhere (see Cell and TreeTableView for example).
Finally, there are a number of pre-built cell factories available in the javafx.scene.control.cell package.
设置单元工厂
public final void setCellFactory(Callback<TreeTableColumn<S,T>,TreeTableCell<S,T>> value)
设置属性 cellFactory 的值。属性描述:该列中所有单元格的单元格工厂。单元工厂负责为单个 TreeTableColumn 呈现每个 TreeTableCell 中包含的数据。默认情况下,TreeTableColumn 使用默认的单元工厂,但这可以替换为自定义实现,例如以不同的方式显示数据或支持编辑。在其他地方有很多关于创建自定义单元工厂的文档(例如,请参阅 Cell 和 TreeTableView)。
最后,javafx.scene.control.cell 包中提供了许多预构建的单元工厂。
taken out from Java 8 API Doc.
从Java 8 API Doc 中取出。
so something like this should be going more into the right direction:
所以像这样的事情应该更朝着正确的方向发展:
public static <S> Callback<TableColumn<S,String>, TableCell<S,String>> forTableColumn() {
return forTableColumn(new DefaultStringConverter());
}
or something like this depending on what excactly you want to give into the Cell.
或类似的东西,这取决于您想给 Cell 提供什么。
setCellFactory(TextFieldTableCell.<DataModel, Integer>forTableColumn(new IntegerStringConverter()));
these code snippets are taken from This StackOverflow Thread
这些代码片段取自This StackOverflow Thread
and last this link could help you too: TableView Cell Tutorial
最后这个链接也可以帮助你: TableView Cell Tutorial
So this should give you some more light in the dark about what might be causing the problem.
所以这应该让你在黑暗中更多地了解可能导致问题的原因。