我试图编写一个AnimalGroup
工厂类,它返回一个包含各种不同类型Animal
的实例。不幸的是,由于Java泛型的限制,我被迫重复代码。我已经尝试了所有可能的通配符组合,我可以想到没有运气。
以下是代码:
public AnimalGroup<?> getAnimalGroup (String animalName) {
if(animalName.equals("Yetti")) {
AnimalGroup<Yetti> animalGroup = new AnimalGroup<>(Yetti.class);
animalGroup.doSomeProcessing();
return animalGroup;
}
else {
AnimalGroup<Doge> animalGroup = new AnimalGroup<>(Doge.class);
animalGroup.doSomeProcessing();
return animalGroup;
}
}
这是我想做的事情:
public AnimalGroup<?> getAnimalGroup (String animalName) {
Class<?> animalClass = Doge.class;
if(animalName.equals("Yetti")) {
animalClass = Yetti.class;
}
AnimalGroup<animalClass> animalGroup = new AnimalGroup<>(animalClass);
animalGroup.doSomeProcessing();
return animalGroup;
}
更新:
使用<? extends Animal>
解决方案,以下附加处理代码不再有效:
// Pseudo-ish code
public <T extends Animal> void setAnimals (T animals) { this.animals = animals; }
List<? extends Animal> animals = getAnimals(animalClass);
animalGroup.setAnimals(animals);
给出的错误令人困惑:
setAnimals(java.util.List<capture<? extends Animal>>) in AnimalGroup cannot be applied to (java.util.List<capture<? extends Animal>>)
任何帮助都很大。谢谢! 本。
答案 0 :(得分:1)
Doge和Yeti是否扩展了相同的Animal类?如果是,那么你可以做
public AnimalGroup<? extends Animal> getAnimalGroup (String animalName) {
Class<? extends Animal> animalClass = Doge.class;
if("Yetti".equals(animalName)) {
animalClass = Yetti.class;
}
AnimalGroup<? extends Animal> animalGroup = new AnimalGroup<>(animalClass);
animalGroup.doSomeProcessing();
return animalGroup;
}
如果他们没有,那么他们应该:)。
我无法理解编辑我做了POC并且以下代码有效(假设接口A并实现类B和C:
private static List<? extends A> generateObjects(boolean isItB) {
if (isItB) {
return new ArrayList<B>() {
{
add(new B());
}
};
} else {
return new ArrayList<C>() {
{
add(new C());
}
};
}
}
private static void consumeObjects(List<? extends A> consuming) {
for (A a : consuming) {
a.doStuff();
}
}
public static void main(String[] args) {
List<? extends A> generatedBs = generateObjects(false);
consumeObjects(generatedBs);
}
答案 1 :(得分:1)
您可以尝试enum
:
class AnimalGroup<T> {
AnimalGroup(Class<T> itsClass) {
}
public void doSomeProcessing() {
}
}
class Yetti {
}
class Dog {
}
// Connects the name of the animal with the
enum Animal {
Dog(Dog.class),
Yetti(Yetti.class),
// Can also have aliases this way.
AbominableSnowman(Yetti.class);
final Class itsClass;
Animal(Class c) {
itsClass = c;
}
}
public AnimalGroup<?> getAnimalGroup(String animalName) {
Animal animal = Animal.valueOf(animalName);
AnimalGroup<?> g = new AnimalGroup<>(animal.itsClass);
g.doSomeProcessing();
return g;
}
答案 2 :(得分:1)
您可以尝试在没有使用参数化泛型方法的纯泛型的String类名的情况下执行此操作:
class Wrapper {
public <T> AnimalGroup<T> getAnimalGroup (Class<T> cl) {
AnimalGroup<T> animalGroup = new AnimalGroup<T>(cl);
animalGroup.doSomeProcessing();
return animalGroup;
}
}
然后,AnimalGroup和Animal类可能如下所示:
class AnimalGroup<T> {
private Class<T> cl;
public AnimalGroup(Class<T> cl) {
this.cl = cl;
}
public void doSomeProcessing() {
System.out.println(cl);
/*
here i just printout the classname, but you can do proccessing like this
if (cl.equals(Yetti.class)) do one thing, else do another, etc.
*/
}
}
class Yetti{}
class Dog{}
一个简单的测试:
public class HelloWorld{
public static void main(String []args){
Wrapper an = new Wrapper();
an.getAnimalGroup(Yetti.class);
//new AnimalGroup<String>(String.class).doSomeProcessing();
}
}
返回以下输出
class Yetti
如您所见,您的动物根据存储在AnimalGroup类的Class cl变量中的类型进行区分。
答案 3 :(得分:1)
以下是使用查找Map<String, Class<? extends Animal>>
的解决方案:
private static Map<String, Class<? extends Animal>> map = new HashMap<String, Class<? extends Animal>>() {
{
put("Yetti", Yetti.class);
put("Doge", Doge.class);
}
};
public static AnimalGroup<? extends Animal> getAnimalGroup(String animalName) {
AnimalGroup<? extends Animal> animalGroup = new AnimalGroup<>(map.get(animalName));
animalGroup.doSomeProcessing();
return animalGroup;
}