0

I am trying to design my class using generics. The following code compiles and works well:

public class Main {
static class TestDataProvider {
    public String getString(){
        return "Data provider. Test String";
    }
    public int getInteger() {
        return 1510872341;
    }
    public double getReal() {
        return 34.6729;
    }
}

interface DataGetterType <T> {
    T getData();
}

static class Column <T> {
    public String getName() {
        return nameTag;
    }
    public String getDataType(){
        return dataTypeTag;
    }

    public T getData(){
        return getter.getData();
    }
    public Column(String name, String type, DataGetterType<T> getterObj){
        nameTag = name;
        dataTypeTag = type;
        getter = getterObj;
    }
    private final String nameTag;
    private final String dataTypeTag;
    private final DataGetterType<T> getter;
}

static class StringColumn extends Column<String> {
    StringColumn(String name, TestDataProvider provider) {
        super(name, "TEXT", provider::getString);
    }
}

static class IntegerColumn extends Column<Integer> {
    IntegerColumn(String name, TestDataProvider provider) {
        super(name, "INTEGER", provider::getInteger);
    }
}

static class RealColumn extends Column<Double> {
    RealColumn(String name, TestDataProvider provider) {
        super(name, "REAL", provider::getReal);
    }
}

public static void main(String[] args) {
    TestDataProvider myProvider = new TestDataProvider();
    StringColumn modelColumn = new StringColumn("model", myProvider);
    IntegerColumn dateColumn = new IntegerColumn("year_of_production", myProvider);
    RealColumn weightColumn = new RealColumn("weight", myProvider);

    System.out.print(modelColumn.getDataType() + " " + modelColumn.getName() + ": " + modelColumn.getData() + ";\n" +
            dateColumn.getDataType() + " " + dateColumn.getName() + ": " + dateColumn.getData() + ";\n" +
            weightColumn.getDataType() + " " + weightColumn.getName() + ": " + weightColumn.getData() + ";\n");
}

}

But when I try to make data provider a generic parameter too I get a compile error 'Cannot resolve method 'getString''

    static class StringColumn<DataProvider> extends Column<String> {
        StringColumn(String name, DataProvider provider) {
            super(name, "TEXT", provider::getString); // <- cannot resolve method 'getString'
        }
    }

I need help with making DataProvider a generic parameter for Column class descendants.

Yury Rudakou
  • 411
  • 3
  • 15
  • Can't you use a `DataProvider` interface with a `getString` method? – Jorn Vernee Nov 21 '17 at 11:49
  • @JornVernee This is simplified code. I plan to use SQLiteCursor wich has methods getString(int), getDouble(int ) etc. as data provider or another custom DataProvider class for test purposes – Yury Rudakou Nov 21 '17 at 11:58
  • So create an interface with all those methods? I'm not sure what you want to get by making `DataProvider` generic. – Jorn Vernee Nov 21 '17 at 12:08
  • @JornVernee The intention was to pass anything that has methods getString(int), getInteger(int), getDouble(int) etc., not necessarily the android.database.AbstractCursor interface descendants. – Yury Rudakou Nov 21 '17 at 12:30
  • 1
    Oh I see, well, you can't dynamically discover methods on a generic type. You could look up the method with reflection or method handles and then call that. But it's certainly not as pretty. – Jorn Vernee Nov 21 '17 at 12:59

0 Answers0