Java 如何基于某个类实例化特定的实现?

Java 如何基于某个类实例化特定的实现?,java,reflection,interface,Java,Reflection,Interface,我有几个扩展bean的对象: public class Fruit {} public class Banana extends Fruit {} public class Pear extends Fruit {} 我有一个具有不同实现的接口,每个bean对应一个接口 public interface Milkshake { public String doMilkshake(); } public class FruitMilkshake implements Milksha

我有几个扩展bean的对象:

public class Fruit {}

public class Banana extends Fruit {}

public class Pear extends Fruit {}
我有一个具有不同实现的接口,每个bean对应一个接口

public interface Milkshake {
    public String doMilkshake();
}

public class FruitMilkshake implements Milkshake {
    public String doMilkshake() {
        return "Fruit Milkshake!";
    }
}

public class BananaMilkshake implements Milkshake {
    public String doMilkshake() {
        return "Banana Milkshake!";
    }
}

public class PearMilkshake implements Milkshake {
    public String doMilkshake() {
        return "Pear Milkshake!";
    }
}
如何根据bean的具体类型实例化正确的实现

现在我已经使用了类型化和映射来“映射”正确的实现。 像这样:

public void hungry(Fruit fruit) {
    Map<String, String> obj2impl = new HashMap<String, String>();
    obj2impl.put("Fruit", "FruitMilkshake");
    obj2impl.put("Banana", "BananaMilkshake");
    obj2impl.put("Pear", "PearMilkshake");

    String name = fruit.getClass().getCanonicalName();
    String implName = obj2impl.get(name);
    Milkshake milkshake = (Milkshake) Class.forName(implName).newInstance();

    milkshake.doMilkshake(fruit);
}



public interface Milkshake <T t> {
    public String doMilkshake(T t);
}

public class FruitMilkshake implements Milkshake<Fruit> {
    public String doMilkshake(Fruit fruit) {
        return "Fruit Milkshake!";
    }
}

public class BananaMilkshake implements Milkshake<Banana> {
    public String doMilkshake(Banana banana) {
        return "Banana Milkshake!";
    }
}

public class PearMilkshake implements Milkshake<Pear> {
    public String doMilkshake(Pear pear) {
        return "Pear Milkshake!";
    }
}
公共空间饥饿(水果){
Map obj2impl=new HashMap();
obj2impl.put(“水果”、“水果奶昔”);
obj2impl.put(“香蕉”、“香蕉奶昔”);
简单地说(“梨”、“梨奶昔”);
字符串名称=fruit.getClass().getCanonicalName();
字符串implName=obj2impl.get(name);
Milkshake Milkshake=(Milkshake)Class.forName(implName).newInstance();
奶昔,多米尔克奶昔(水果);
}
公共界面奶昔{
公共字符串doMilkshake(T);
}
公共类水果奶昔实现奶昔{
公共串多米尔克奶昔(水果){
返回“水果奶昔!”;
}
}
公共类BananaMilkshake实现Milkshake{
公共字符串doMilkshake(香蕉){
返回“香蕉奶昔!”;
}
}
公共类PearMilkshake实现Milkshake{
公共字符串多米尔克(梨){
返回“梨奶昔!”;
}
}
实现这一目标的更好方法

实现这一目标的更好方法

好吧,一个出发点是避免思考类的名称:

Map<String, Class<? extends Milkshake>> obj2impl =
    new HashMap<String, Class<? extends Milkshake>>();
obj2impl.put("Fruit", FruitMilkshake.class);
obj2impl.put("Banana", BananaMilkshake.class);

...

Milkshake milkshake = obj2impl.get(text).newInstance();
编辑:重读这篇文章后,你也可以去掉文本部分,得到一个
Map
public类{

public ClassI显然没有使用这些名称。这只是一个例子。@Enrichman:我不是说这些名称是真名,但你在地图中使用了类名的文本,而你可以使用类文本。这就是我的观点。啊,好的,明白了。你是对的。:)顺便说一句,我在我的项目中使用了Guice,所以提供程序的东西会很有用。我oC是我认为的唯一方法。你不应该在每次调用
Hunger
时都重新创建水果映射。而是将该映射作为一个实例变量。或者打开水果名称。现在你正在捆绑
水果、香蕉和梨
来了解
奶昔
。为什么他们会了解奶昔?因为你可以拿一个水果做一杯奶昔吗?这是一个完全合理的想法。他没有说明他们之间有什么确切的了解,但他们都是公开的,所以我想他们都认识。如果他计划有很多不同的选择,他怎么知道做什么呢?对于每一个给的水果,一定有只有一种方法可以生产,否则饥饿的方法就不知道该用什么了。因此,如果每个水果都有一个对应的产品可以生产,这就很好了
Map<String, Provider<Milkshake>> map = ...;
// Fill the map with providers, some of which could create a new instance,
// and some could reuse an existing one

...

Milkshake milkshake = map.get(text).get();
public class Fruit {
    public Class<? extends Milkshake> getMilkshakeClass() {
        return Milkshake.class;
    }
}

public class Banana extends Fruit {
    public Class<? extends Milkshake> getMilkshakeClass() {
        return Banana.class;
    }
}

public class Pear extends Fruit {
    public Class<? extends Milkshake> getMilkshakeClass() {
        return PearMilkshake.class;
    }
}
public abstract class AbstractFruit {
    public abstract Class<? extends Milkshake> getMilkshakeClass();
}