0

I need to create and return a generic list of static nested classes objects.

For example :

if there is a class Outer containing static nested classes as InnerOne/Two/Three and so on.. with their own members and methods.

and

I am trying to create and retrieve their instance through Factory class.

How can I do it ?

How should I declare and define my "genericList" as shown in below code.

so that later I can "typecast" the list objects to their respective class object by making use of "instanceof" operator and call upon their respective "overloaded" functions ??

public class Outer{

    public static class InnerOne{
        //members and methods
    };

    public static class InnerTwo{
        //members and methods
    };

    public static class InnerThree{
        //members and methods
    };
}

public class factory{

    public static List<?> getInstanceList(List<String> instancetypes){
        List<?> genericList = new ArrayList<>();
        for(String instanceType : instancetypes){
            if(instanceType.equals("InnerOne")){
                genericList.add(new InnerOne());
            }
            else if(instanceType.equals("InnerTwo")){   
                genericList.add(new InnerTwo());
            }else{
                genericList.add(new InnerThree());
            }
        }
         return genericList;
    }
}
Dhanesh Khurana
  • 159
  • 1
  • 13
  • This eerily resembles http://stackoverflow.com/questions/32614453/use-the-command-line-to-make-new-objects/32614646#32614646 but you need a common ancestor, and you will only see them along the ancestor, not the concrete type. – EpicPandaForce Sep 18 '15 at 14:25
  • This feels like an [XY problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) whose proper solution is [ServiceLoader](http://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html). – VGR Sep 18 '15 at 15:29

2 Answers2

0

First, I see no generic here because the inner classes don't share a common ancestor (except Object) and there's nothing to make the method generic on. Second, your method needs a return type. Something like,

public static List<Object> getInstanceList(List<String> instancetypes){
    List<Object> genericList = new ArrayList<>();
    // ...
    return genericList;
}

You can use instanceof on the Object; and then typecast to the correct type. I would prefer that you program to a common interface and return a List of that type. But you can do something like

for (Object obj : genericList) {
    if (obj instanceof InnerOne) {
        InnerOne one = (InnerOne) obj;
    }
}
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
0

You could make the genericList of type List<Object>, which allows you to add just anything to the list. How ever if you want to access members or methods defined in an inner class, you would have to type cast them (as you said).

If the inner classes have anything in common, you can extract that into a super class:

public class Outer{

    public abstract static class InnerSuper{
        public abstract void method();
    };

    public static class InnerOne extends InnerSuper{
        //members and methods

        @Override
        public void method(){
            System.out.println("InnerOne.method()");
        }
    };

    public static class InnerTwo extends InnerSuper{
        //members and methods

        @Override
        public void method(){
            System.out.println("InnerTwo.method()");
        }
    };

    public static class InnerThree extends InnerSuper{
        //members and methods

        @Override
        public void method(){
            System.out.println("InnerThree.method()");
        }
    };
}

public class factory{

    public static List<InnerSuper> getInstanceList(List<String> instancetypes){
        List<InnerSuper> genericList = new ArrayList<>();
        for(String instanceType : instancetypes){
            if(instanceType.equals("InnerOne")){
                genericList.add(new InnerOne());
            }
            else if(instanceType.equals("InnerTwo")){   
                genericList.add(new InnerTwo());
            }else{
                genericList.add(new InnerThree());
            }
        }
        return genericList;
    }
}

In that case the genericList would be of type List<InnerSuper>. If you now want to call method() you can do that as follows:

List<String> instanceTypes = new ArrayList<>();
instanceTypes.add("InnerTwo");
instanceTypes.add("InnerOne");
List<InnerSuper> instances = factory.getInstanceList(instanceTypes);
instances.get(0).method();

This code would give the following output:

InnerTwo.method()
moonlight
  • 359
  • 6
  • 17