作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个类Column
,它描述了类似 SQL 的表的列:
public interface Column<S extends Schema<S>, T> {
default String encode(final T value) {
return value.toString();
}
}
列包含特定类型(整数、字符串...),并具有实用函数来将该类型的实例转换为字符串(这对于日志记录很有用)。
接下来,我有一个类Schema
它描述了表的架构:
public interface Schema<S extends Schema<S>> {
List<Column<S, ?>> getColumns();
}
模式包含列列表。
让我们创建一个只有一列的具体模式:
public static class MySchema implements Schema<MySchema> {
public static final Column<MySchema, Integer> ID = new Column<MySchema, Integer>(){};
@Override
public List<Column<MySchema, ?>> getColumns() {
return Collections.singletonList(ID);
}
}
接下来,我有一个类MyData
其中包含与架构对应的数据:
public static class MyData<S extends Schema<S>> {
public <T> T get(final Column<S, T> column) {
return (T) new Integer(164); // actual implementation left out
}
}
手动编码列的值非常简单:
final MySchema s = new MySchema();
final MyData<MySchema> d = new MyData<>();
System.out.println("encoded identifier: " + MySchema.ID.encode(d.get(MySchema.ID)));
现在,让我们动态地尝试一下:
for (final Column<MySchema, ?> column : s.getColumns()) {
System.out.println("encoded identifier: " + column.encode(d.get(column)));
}
这行不通,因为 d.get(column)
被推断为 capture<?>
,这不是什么Column.encode()
接受。
我该如何解决这个问题?我明白这里出了什么问题( Column.encode(T value)
只接受一个 T
,我们现在没有),但我找不到一个解决方案,它不会失去我们通过只接受一个来强制执行的类型保证T
.
作为 fiddle ,这里是完整的代码:
public class Test {
public interface Column<S extends Schema<S>, T> {
default String encode(final T value) {
return value.toString();
}
}
public interface Schema<S extends Schema<S>> {
List<Column<S, ?>> getColumns();
}
public static class MyData<S extends Schema<S>> {
public <T> T get(final Column<S, T> column) {
return (T) new Integer(164); // actual implementation left out
}
}
public static class MySchema implements Schema<MySchema> {
public static final Column<MySchema, Integer> ID = new Column<MySchema, Integer>(){};
@Override
public List<Column<MySchema, ?>> getColumns() {
return Collections.singletonList(ID);
}
}
public static void main(final String a[]) {
final MySchema s = new MySchema();
final MyData<MySchema> d = new MyData<>();
System.out.println("encoded identifier: " + MySchema.ID.encode(d.get(MySchema.ID)));
for (final Column<MySchema, ?> column : s.getColumns()) {
System.out.println("encoded identifier: " + column.encode(d.get(column)));
}
}
}
最佳答案
您可以使用通用参数创建辅助函数 T
这让你有一个 Column<T>
而不是 Column<?>
:
public static void main(final String a[]) {
final MySchema s = new MySchema();
final MyData<MySchema> d = new MyData<>();
for (final Column<MySchema, ?> column : s.getColumns())
encode(column, d);
}
private static <T> void encode(Column<T> column, MyData<MySchema> d) {
System.out.println("encoded identifier: " + column.encode(d.get(column)));
}
另一种可能性是使用相同的技巧 并提供一个方便的方法MyData.getEncoded
:
public static class MyData<S extends Schema<S>> {
public <T> T get(final Column<S, T> column) {...}
public <T> String getEncoded(final Column<S, T> column) {
return column.encode(get(column));
}
}
关于java - 泛型 - 动态使用类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33417959/
我是一名优秀的程序员,十分优秀!