我应该创建一个新的Object,它扩展了JavaFX中TableView的功能(让我们称之为TableViewPlus - 我没有更好的名字,但是大声笑)。一个新功能应该是每个TableColumn的过滤器,取决于列中的类型。
例如:我有类型" Person"的对象,其中包含名称(String)的字段,出生日期(LocalDate)和ID(整数)。这些是在我的TableViewPlus之外定义的,只是使用以下方法传递给它:
public void addColumns(TableColumn<T, ?>... columns) {
table.getColumns().addAll(columns);
}
稍后,我想为每个表添加过滤器(作为上下文菜单)。对于name列,我需要一个带有简单字符串匹配的过滤器,对于日期列,我需要一个带有datepicker的过滤器,依此类推......现在问题是:如何判断我的列中的数据类型是什么? (我怎么知道哪种类型&#39;?&#39;是?)。
我的解决方案如下,只有在表格中已有数据时才有效:
private void createFilters() {
for (TableColumn<T,?> col : table.getColumns()) {
if (col.getCellData(0).getClass().equals(String.class) {
//create string filter
} else if (col.getCellData(0).getClass().equals(Integer.class) {
//create int filter
} else if (col.getCellData(0).getClass().equals(LocalDate.class) {
//create date filter
}
}
}
显然这很糟糕! :d
如果不能直接使用给定的东西,另一种可能的解决方案可能是直接用列创建过滤器。所以我不会让TableColumns传递给我的TableViewPlus,只是一个名字和一个回调,就像这样:
public <S> void test(String name, Callback<TableColumn.CellDataFeatures<T,S>,ObservableValue<S>> value) {
TableColumn<T,S> col = new TableColumn(name);
col.setCellValueFactory(value);
table.getColumns().add(col);
//if (S == String.class) {} //this line does not work because "Cannot find Symbol: variable S"
}
此方法到目前为止工作正确地创建了列并填充了数据(因此S以某种方式正确设置)并且我从上面的createFilters()方法得到相同的结果,但这只是使用表中的第一项再次。我如何获得S的课程?
答案 0 :(得分:1)
您实际需要的是 type token 。如果要独立访问该类型,请将类型标记传递给类的构造函数。
这是一个简化的示例,您可以轻松地使用自己的类:
public class Generified<T> {
private T value;
private Class<T> typeToken;
public Generified(Class<T> typeToken) { this.typeToken = typeToken; }
public T get() { return value; }
public void set(T value) { this.value = value; }
public void someMethod() { System.out.println(typeToken.getName()); }
public static void main(String[] args) {
Generified<Integer> generified = new Generified<>(Integer.class);
generified.someMethod();
}
}
运行此程序将生成输出
java.lang.Integer中
请注意,您仍然具有类型安全性。以下代码 - 例如 - 将无法编译:
Generified<Integer> generified = new Generified<>(String.class);
答案 1 :(得分:0)
你想要的是不可能的。在Java中,泛型只在编译时出现 。编译代码后,每个类型参数基本上都成为Object
引用。因此,在朗姆酒时,不可能再找出泛型类型的类型参数。这称为类型擦除。这对于较新的Java版本是向后兼容的是必要的。
一个解决方案是明确存储某处内容的类型。 Class
是Java中的普通类,因此您可以使用此类型的字段。
答案 2 :(得分:0)
您可以这样做:
private final Map<TableColumn<T,?>, Class<?>> columnTypes = new HashMap<>();
public <S> void addColumn(TableColumn<T,S> col, Class<S> type) {
getColumns().add(col) ;
columnTypes.put(col, type);
}
现在,您可以在需要时检索列的类型,并按照
的方式执行操作if (columnTypes.get(col) == String.class) {
// create String filter...
}
等
它并不漂亮,但它比假设所有表都有数据并且数据类型都相同更好。