我有Dog.java
,Cat.java
,Bird.java
,Fish.java
,Not_Listed.java
等类。我还有ID.java
只保留一些最终的int映射:
public class ID{
public static final int CAT = 1;
public static final int DOG = 3; // there maybe some integers skipped
public static final int FISH = 4; // but all integers are unique
public static final int BIRD = 6;
public static final int NOT_LISTED = -1;
}
上面列出的所有类都扩展了Animal.java
类。
我需要的是" 6"我需要创建一个Bird
对象,给出" 1"我需要创建Cat
对象。鉴于" 2"或" 5"我可以返回一个Not_Listed
对象或只是抛出一个错误(两个都有效)。我可以使用switch case
或HashMap
来完成,但我的列表有点长,我不想在列表增长时更新代码。所以我提出了反思,但我不知道该怎么做?
欢迎任何其他有效的解决方案。很抱歉对于反思是noob。提前谢谢。
编辑:ID 必须
答案 0 :(得分:2)
你不需要反思。
创建一个枚举而不是你的id类,并在枚举中有一个类引用,即:
enum Animal {
CAT(1, Cat.class),
DOG(2, Dog.class),
FISH(3, Fish.class);
private final Class clazz;
private final int id;
Animal(int id, Class clazz) {
this.id = id;
this.clazz = clazz;
}
public Object generateInstance() {
return clazz.generateInstance();
}
public class getGeneratedClass() {
return clazz;
}
public int getId() {
return id;
}
}
这利用了Java的特性,它允许枚举成为功能齐全的类,并记录要在枚举中的每个条目中使用的Class
。然后,只要该类具有0参数构造函数,您就可以使用Class
按需生成新实例。
要使用它,请执行以下操作:
Animal.DOG.generateInstance() // Returns a Dog object
Animal.CAT.generateInstance() // Returns a Cat object
如果你想从id获得一个类型,你可以在枚举中建立一个HashMap
来进行查找,或者只是循环遍历enum.values()寻找一个匹配。
答案 1 :(得分:1)
一种完全不同的方法,所以我将其作为一个单独的答案。
只需创建一个从id到class的Map:
public static final int CAT = 1;
public static final int DOG = 3; // there maybe some integers skipped
public static final int FISH = 4; // but all integers are unique
public static final int BIRD = 6;
public static final int NOT_LISTED = -1;
Map<Integer, Class> classMap = new HashMap<>();
classMap.put(CAT, Cat.class);
classMap.put(DOG, Dog.class);
classMap.put(FISH, Fish.class);
public Object generateInstance(int id) {
// Will throw NullPointerException if id isnt in map, you might want to consider some checks
return classMap.get(id).generateInstance();
}
那会做你想要的,你真的应该看看我在其他答案中发布的枚举设计 - 从长远来看它会给出更好的结果。
答案 2 :(得分:0)
这样就有了工厂设计模式。您可以在各自的班级中注册每个动物类(例如猫,鱼,狗,鸟等)。
请参阅http://www.oodesign.com/factory-pattern.html
上的课程注册 - 避免反思你可以拥有一个AnimalFactory,它将ID的地图保存到实现Facotry Method的类。然后,您将在Animal的每个特定实现中注册它。这样AnimalFactory就不需要改变了,只需要添加的每个新Animal都需要注册特定的工厂:
public class Dog extends Animal
{
...
static
{
AnimalFactory.instance().registerAnimal(ID.DOG, new DogCreator());
}
...
}
public class DogCreator extends AnimalFactory
{
//Abstract factory method in AnimalFactory that gets called to return the Animal
public Animal createAnimal
{
return new Dog();
}
}
您还可以拥有一个使用反射来创建新类的通用动物创建者(假设每个Animal都有一个空构造函数)。这仍然需要您在每个Animal实现中注册您的特定ID:
public class Dog extends Animal
{
...
static
{
AnimalFactory.instance().registerAnimal(ID.DOG, Dog.class);
}
...
}
然后AnimalFactory可以使用反射来创建实例:
public Animal createAnimal(ID id)
{
return animalMap.get(id).newInstance();
}