1

quick question about creating objects when given a Class object. Or maybe I need to go about this differently. First off my plan, I am writing a method that will take an array of File objects, and read each one into a Set, where each set is then appended to a list and the list returned. Below is what I have:

private static List<Set<String>> loadFiles(File[] files, Class whatType, Charset charSet){
    List<Set<String>> setList = new ArrayList<Set<String>>(files.length);

    try {
        for(File f : files){
            BufferedInputStream bs = new BufferedInputStream(new FileInputStream(f));
            InputStreamReader r = new InputStreamReader(bs, charSet);
            BufferedReader br = new BufferedReader(r);

            Set<String> set = new HashSet<>(); //This is the problem line
            String line = null;

            while( (line = br.readLine()) != null){
                set.add(line.trim());

            }

            br.close();
            setList.add(set);
        }

        return setList;
    } catch (FileNotFoundException e) {
        //Just return the empty setlist
        return setList;
    } catch (IOException e) {
        //return a new empty list
        return new ArrayList<Set<String>>();
    }
}

But what I want is to allow the user of the method to specify the type of Set to instantiate (as long as it contains Strings of course). That is what the 'whatType' param is for.

All my research has lead me to how to instantiate an object given the class name, but that is not really what I am after here.

4
  • 1
    Do you mean e.g. HashSet vs. TreeSet? Commented Aug 23, 2016 at 16:44
  • 1
    Why? It's generally expected in Java that you'll return your own new set from a method like this. If there's a compelling reason for using the caller's version, have them pass it in. Commented Aug 23, 2016 at 16:44
  • @chrylis The main reason for this is that, internally, the project I am working on we do a lot of loading from files and storing those Strings in sets: Hash, Tree, our own classes that implement Set. And the type of Set used depends on the situation. This just allows us to simplify the code base and write less boilerplate with casting. This is for the instances where the underlying implementation is important. Commented Aug 30, 2016 at 15:13
  • 1
    Still don't see why you can't have the caller pass in the set object. Commented Aug 30, 2016 at 15:17

3 Answers 3

2

If you can use Java8, you can solve this problem easily. Declare the method as follows:

private static List<Set<String>> loadFiles(File[] files, Supplier<Set> setSupplier, Charset charSet)

Change your problem line to:

Set<String> set = setSupplier.get();

Then, in each call to this method, the setSupplier param can be easily provided using method references: HashSet::new, TreeSet::new...

Sign up to request clarification or add additional context in comments.

1 Comment

I should have specified that I am still stuck in Java 7 world, but for 8 this is a really great and worked when I tested it in a little mock 8 project
2

How about using Class.newInstance() method? I coded a simple example for you:

public <T extends Set> void myMethod(Class<T> type) {
  T object;
  try {
    object = type.newInstance();
  } catch (InstantiationException e) {
    e.printStackTrace();
  } catch (IllegalAccessException e) {
    e.printStackTrace();
  }
}

public void caller() {
  myMethod(HashSet.class);
}

Is this what you are looking for?

Comments

1

If you assume the class has a no-argument accessible constructor, you're basically a newInstance() call away:

Set<String> set = (Set<String) whatType.newInstance();

Note that if you define whatType as a Class<? extends Set> instead of just a raw Class, you can get rid of this ugly cast too.

1 Comment

I chose to accept this answer because I am still using Java 7 for this project and it worked perfectly

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.