gpt4 book ai didi

java - 泛型 - 动态使用类型

转载 作者:行者123 更新时间:2023-11-30 10:55:11 25 4
gpt4 key购买 nike

我有一个类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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com