Dependecy Injection of collections
I have a class A that works with List<String>. But nobody outside this class should need to know that it works with strings. However, I also wa开发者_开发问答nt to supply the concrete implementation the class should use for it's List (via dependency injection).
A should look like this
public class A {
  private ListFactory listFactory; //this gets injected from the outside
  public A(ListFactory listFactory) {
    this.listFactory = listFactory;
  }
  public void a() {
    List<String> = listFactory.createList();
    //...
  }
}
And the caller class B something like this
public class B {
  public void b() {
    ListFactory factory = new ArrayListFactory(); //we want class A to use ArrayList
    A a = new A(factory);
    //...
  }
}
ListFactory would be an interface which is implemented by ArrayListFactory to create ArrayLists.
Quintessence:
I don't want that B has to mention String somewhere. And I also don't want that A has to mention ArrayList somewhere.
Is this possible? And how would ListFactory and ArrayListFactory have to look?
This is simpler than you're making it, I think:
public interface Factory {
    public <T> List<T> create();
}
public class FactoryImpl implements Factory {
    public <T> ArrayList<T> create() {
        return new ArrayList<T>();
    }
}
...
Factory f = new FactoryImpl();
List<String> strings = f.create();
...
Seems you wrote all you need. Factories will look like:
interface ListFactory<K, T extends List<K>> {
    T create();
}
class ArrayListFactoryImpl implements ListFactory<String, ArrayList<String>> {
    public ArrayList<String> create() {
        return new ArrayList<String>();
    }
}
class Sample {
      public static void main(String[] args) {
          ListFactory<String, ArrayList<String>> factory = new ArrayListFactoryImpl();
          factory.create().add("string");
      }
}
Another attempt thanks to more clear understanding of the issue:
interface ListFactory<T extends List> {
    T create();
}
class ArrayListFactoryImpl implements ListFactory<ArrayList> {
    public ArrayList create() {
        return new ArrayList();
    }
}
class ListWrapper<T> implements List<T> {
    private final List impl;
    public ListWrapper(List impl) {
        this.impl = impl;
    }
    public boolean add(T t) {
        if (!String.class.isAssignableFrom(t.getClass()))
            throw new RuntimeException("Aaaaa");
        return impl.add(t);
    }
    // so on...
}
class A {
    A(ListFactory factory) {
        List<String> stringsOnly = new ListWrapper<String>(factory.create());
    }
}
class Sample {
      public static void main(String[] args) {
          ListFactory<ArrayList> factory = new ArrayListFactoryImpl();
          new A(factory);
      }
}
 
         加载中,请稍侯......
 加载中,请稍侯......
      
精彩评论