Java 泛型-动态使用类型

Java 泛型-动态使用类型,java,generics,Java,Generics,我有一个类列,它描述了类似SQL的表的列: public interface Column<S extends Schema<S>, T> { default String encode(final T value) { return value.toString(); } } 架构包含列的列表 让我们创建一个只包含一列的具体模式: public static class MySchema implements Schema<MyS

我有一个类
,它描述了类似SQL的表的列:

public interface Column<S extends Schema<S>, T> {
    default String encode(final T value) {
        return value.toString();
    }
}
架构包含列的列表

让我们创建一个只包含一列的具体模式:

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);
    }
}
手动编码列的值非常简单:

final MySchema s = new MySchema();
final MyData<MySchema> d = new MyData<>();

System.out.println("encoded identifier: " + MySchema.ID.encode(d.get(MySchema.ID)));

您可以使用通用参数
T
创建帮助函数,该参数允许您使用
列而不是


您好,如果没有任何您想要实现的内容,很难提出解决方案,但是从我看到的情况来看,列的声明方式、定义列以及列在集合列表中的处理方式存在不一致。在这种情况下,对于encode方法,我会说,如果实现可以针对不同的类型进行更改,那么就会缺少封装。实现应该使用类拥有的值,而不是期望它作为参数。一般来说,转换从?为一个类型(T)需要铸造。这是相当整洁的。但也很尴尬。我创建了一个后续问题:@JesterDaro答案并不尴尬,但Java不允许在语句或块级别定义通用参数,正如您在后续问题中注意到的那样。我忘记接受,对此表示歉意。谢谢提醒!我觉得这很尴尬,因为它使代码膨胀。就这样:)。我并不是说你的回答本身就很尴尬。
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)));
}
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)));
        }
    }
}
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)));
}
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));
    }
}