0

So I'm working with JSON in Java and JSON can have a base of either an Array or an Object. In my Config class, I take a class as an argument so I can create the file accordingly if it doesn't exist. I also store the class as a private field so I know in future.

However, when I get to reading the file, I'd prefer to have multiple return types though the same method name. If I return Object, I then have to cast the returned value which I want to avoid.

Current code:

public class Config {

    private File dir = null;
    private File file = null;
    private Class clazz = null;

    public Config(String program, String fileName, Class root) throws IOException {
        this.dir = new File(System.getProperty("user.home") + File.separator + program);
        if (!this.dir.exists()) {
            this.dir.mkdir();
        }

        this.file = new File(this.dir + File.separator + fileName);
        if (!this.file.exists()) {
            this.file.createNewFile();

            if (root.getName().equals(JSONArray.class.getName())) {
                Files.write(this.file.toPath(), "[]".getBytes());
            } else if (root.getName().equals(JSONObject.class.getName())) {
                Files.write(this.file.toPath(), "{}".getBytes());
            }
        }

        this.clazz = root;
    }

    public JSONArray readConfig() {
        return null;
    }

    public JSONObject readConfig() {
        return null;
    }

}

Is there anyway I can do what I want without having to return Object?

Spedwards
  • 4,167
  • 16
  • 49
  • 106
  • The standard answer is to simply have separate methods (i.e. `readConfigArray()`, `readConfigObject()`) for the separate types of data you intend to read. – dimo414 Jul 06 '15 at 06:38
  • @dimo414 I'm aware it's a standard to do so, however my question is, is it possible to do what I want? – Spedwards Jul 06 '15 at 06:46
  • Have you tried compiling it? – t3dodson Jul 06 '15 at 06:46
  • @t3dodson I'm still making modifications so no, not yet. – Spedwards Jul 06 '15 at 06:50
  • Casting the return value declared as object before returning it will still return an Object; the caller will receive the same object as without casting. Important is the type declared. – Uwe Allner Jul 06 '15 at 07:14

1 Answers1

3

multiple return types though the same method name

well, it is possible to use generic function to achieve that. For example,

public static void main(String[] args) {
    try {
        String t = getObject(String.class);
        Integer d = getObject(Integer.class);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static <T> T getObject(Class<T> returnType) throws Exception {
    if(returnType == String.class) {
        return (T) "test";
    } else if(returnType == Integer.class) {
        return (T) new Integer(0);
    } else {
        return (T) returnType.newInstance();
    }
}

Will the following code even compile?

I'm afraid no. There are few compilation errors such as

public Object readConfig() {
    try {
        // Assume jsonString exists
        return (this.clazz.getDeclaredConstructor(String.class).newInstance(jsonString)); <--- clazz should be getClass()
    } catch (InstantiationException | IllegalAccessException
            | IllegalArgumentException | InvocationTargetException
            | NoSuchMethodException | SecurityException e) {
        e.printStackTrace();
         <---- missing return statement
    }
}
kucing_terbang
  • 4,991
  • 2
  • 22
  • 28
  • That's exactly what I was looking for! Thanks. In the code I asked to compile, it does compile. I had a `return null;` out of the try-catch that I forgot to include in the example. – Spedwards Jul 06 '15 at 07:38