Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何防止Java泛型强制执行重复代码?_Java_Variables_Generics_Duplicates - Fatal编程技术网

如何防止Java泛型强制执行重复代码?

如何防止Java泛型强制执行重复代码?,java,variables,generics,duplicates,Java,Variables,Generics,Duplicates,我试图编写一个AnimalGroup工厂类,它返回一个实例,其中包含各种不同类型的Animal。不幸的是,由于Java泛型的限制,我不得不复制代码。我已经尝试了各种可能的通配符组合等,我能想到没有运气 代码如下: public AnimalGroup<?> getAnimalGroup (String animalName) { if(animalName.equals("Yetti")) { AnimalGroup<Yetti> animalGr

我试图编写一个
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(字符串animalName){
if(animalName.equals(“Yetti”)){
动物群动物群=新动物群(Yetti.class);
动物组。doSomeProcessing();
返回动物群;
}
否则{
动物群动物群=新动物群(Doge.class);
动物组。doSomeProcessing();
返回动物群;
}
}
以下是我想做的:

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;
}
public AnimalGroup getAnimalGroup(字符串animalName){
类动物类=狗类;
if(animalName.equals(“Yetti”)){
animalClass=Yetti.class;
}
AnimalGroup AnimalGroup=新的AnimalGroup(animalClass);
动物组。doSomeProcessing();
返回动物群;
}
更新:


使用
狗和雪人是否扩展了相同的动物类别?如果是的话,你可以做

 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;
    }

公共动物组狗和雪人是否属于同一类动物?如果是的话,你可以做

 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;
    }

public AnimalGroup您可以尝试使用
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;
}
类动物组{
动物群(类及其类){
}
公共无效doSomeProcessing(){
}
}
耶蒂班{
}
班犬{
}
//将动物的名称与
枚举动物{
狗(狗类),
耶蒂(耶蒂班),
//也可以通过这种方式使用别名。
讨厌的雪人(耶蒂班);
期末班;
动物(丙类){
其等级=c;
}
}
public AnimalGroup getAnimalGroup(字符串animalName){
动物=动物。价值(动物名称);
动物群g=新动物群(动物类);
g、 doSomeProcessing();
返回g;
}

您可以尝试使用
枚举

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;
}
类动物组{
动物群(类及其类){
}
公共无效doSomeProcessing(){
}
}
耶蒂班{
}
班犬{
}
//将动物的名称与
枚举动物{
狗(狗类),
耶蒂(耶蒂班),
//也可以通过这种方式使用别名。
讨厌的雪人(耶蒂班);
期末班;
动物(丙类){
其等级=c;
}
}
public AnimalGroup getAnimalGroup(字符串animalName){
动物=动物。价值(动物名称);
动物群g=新动物群(动物类);
g、 doSomeProcessing();
返回g;
}

您可以尝试使用以下参数化泛型方法,使用纯泛型而不使用字符串类名:

class Wrapper {

   public <T> AnimalGroup<T> getAnimalGroup (Class<T> cl) {   

       AnimalGroup<T> animalGroup = new AnimalGroup<T>(cl);
       animalGroup.doSomeProcessing();
       return animalGroup;               
   }
}
   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{}

如您所见,您的动物是根据动物组类的cl类变量中存储的类型进行区分的

您可以尝试使用以下参数化泛型方法使用纯泛型而不使用字符串类名:

class Wrapper {

   public <T> AnimalGroup<T> getAnimalGroup (Class<T> cl) {   

       AnimalGroup<T> animalGroup = new AnimalGroup<T>(cl);
       animalGroup.doSomeProcessing();
       return animalGroup;               
   }
}
   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{}

如您所见,您的动物是根据动物组类的cl类变量中存储的类型进行区分的

这里有一个使用查找
映射的解决方案这里有一个使用查找
映射的解决方案
之间的部分必须是类型名,不能是变量或解析为引用的表达式。@SotiriosDelimanolis Yea,糟透了!所有动物类(Yetti、Doge等)都在同一个包中吗?
之间的部分必须是类型名,不能是变量或解析为引用的表达式。@SotiriosDelimanolis Yea,糟透了!所有动物类(Yetti、Doge等)都在同一个软件包中吗?是的,这确实有效,我以前也使用过相同的解决方案,但这会带来进一步的问题-我更新了问题以演示这一点!你介意给我看一下实际的代码吗?因为你在编辑中写的东西应该可以工作(只是做了一个快速的poc来检查它),虽然你的伪代码有点混合了通配符和泛型参数,但我只是假设了一个输入错误,也许出于安全原因,我错了,我不能显示实际的代码,但我通过在列表中删除类型参数成功地使它工作,也就是说,
ListYes他们这样做,这确实有效,我以前也使用过相同的解决方案,但是这会带来进一步的问题-我已经更新了问题以证明这一点!你介意给我看一下实际的代码吗?因为你在编辑中写的东西应该可以工作(只是做了一个快速的poc来检查它),虽然你的伪代码有点混合了通配符和泛型参数,但我只是假设了一个输入错误,也许出于安全原因,我错了,我不能显示实际的代码,但我通过在列表中删除类型参数成功地使它工作,即
列表
class Yetti
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;
}