4

I would like to have something like this in Java :

import java.util.List;

class Query<T> {
    public List<T> fetch() {
        // Get the table name, T.tableName()
        // Fetch from /api/<table_name>
        // Parse and return data, T.parseJSON(jsonData)
    }
}

The intention here is to have a generic query builder, while each class T defines its specific tableName and parseJSON functions. For example,

class Article {
    public static String tableName() {
        return "article";
    }

    public static List<Article> parseJSON(String jsonData) {
        // Parse the json, build the articles
    }
}

How do I write the fetch function in the Query class?

2
  • 3
    Why do the methods need to be static? Commented Dec 29, 2015 at 17:39
  • 1
    They don't need to be. However, if they are instance methods, I don't have an Article object to use them. Commented Dec 29, 2015 at 17:48

2 Answers 2

1

Simply pass an instance of type T so you have access to the methods of that type. Notice the comments..

public List<T> fetch(T instance) {
    // Get the table name, instance.TableName();

    // Fetch from /api/<table_name>
    // Parse and return data, instance.parseJSON(jsonData)
}
Sign up to request clarification or add additional context in comments.

2 Comments

How are you going to create multiple T instances, for the List? And how are you going to invoke instance.parseJSON on an unbounded generic T? Both of these problems are solvable, but by the time you solve them you've essentially written a Function<String, T> in a more complicated way.
i am not saying this is a "good way" i'm just trying to give the OP an answer under the conditions he has created. A much better way is to provide a fetch that uses an instance that describes all the info needed.
1

This is impossible; the specific instance of the T isn't known at compile time, which is when all static methods are resolved.

A common approach is to make Query<T> abstract, and provide a method:

protected abstract T parse(String data);

You can also use composition: have Query take a Function<String,T> in its constructor, and use it in fetch(). But one way or another, you have to have something that resolves at runtime, which is impossible with static methods.

If you use the composition approach, you can pass the json-reading function to each method, rather than the constructor:

public List<T> fetch(Function<String, T> parser) {
    ...
}

Note that if you do that, you may not even need to make Query generic; you can just make each method generic, as needed:

public class Query {
    public List<T> fetch(Function<String, T> parser) {
        ...
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.