简体   繁体   中英

Get singleton of unknown implementing class without if-statments?

I want to be able to call getInstance() of an unknown implementing class . Is writing if-statements the only solution? See the class Main .

public interface Soup{public Something getSomething();}

public class ChickenSoup implements Soup {
  private static ChickenSoup instance;
  public static ChickenSoup getInstance(){
    if (instance == null){
        instance = new ChickenSoup();
    }
    return instance;
  }
  public Something getSomething(){return Something something;}
}

public class OnionSoup implements Soup {
  private static OnionSoup instance;
  public static OnionSoup getInstance(){
    if (instance == null){
        instance = new OnionSoup();
    }
    return instance;
  }
  public Something getSomething(){
    Something something = somethingElse;
    return something;
  }
}

public class Main{
  private HashMap<String,Soup> soups;
  public Main(){
    buildMap();
  }
  public void callSoupClassGetInstance(String someSoupClassName){
    for (String impClass : soups.values()){
        if (someSoupClassName.contentEquals(impClass.simpleName())){
        //?????????????????????????????????????????

Here I want to be able to get the instance of the implementing class, but I can't because I have to be able to KNOW what I'm casting it to and cast it before I call getInstance() . Can I do this without making a bunch of if statments to check the implementing class name? In other words, is the only solution?:

   if (impClass.simpleName().contentEquals("OnionSoup")){
      OnionSoup.getInstance();
    }

private void buildMap(){
  soups = new HashMap<>();
  //(soupClassNames map) Code here that gets the Soup implementation 
  //class names by iterating class names in the package.
  for (String impClass : soupClassNames.values()){
    Class soupClass = Class.forName(impClass);
    soups.add(soupClassName,soupClass);
  }

You can use Java Reflections like this to invoke a static method of a class you have its name for.

try {
    Class<?> clazz = Class.forName( "OnionSoup" );
    Method method = clazz.getMethod("getInstance");
    method.invoke(null);
} catch( ClassNotFoundException | NoSuchMethodException |  IllegalAccessException |InvocationTargetException |SecurityException ex) {
    ex.printStackTrace();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM