我正在代码中实现依赖注入。
我已经到了一个配置了名为config.properties的属性文件的地步。我也知道如何将属性字符串反映到一个对象中。
问题是,当我进行反射时,Java表示类型将为Class<?>
,并且我希望它为通用类型D
,因此我可以重用与此类耦合的代码。
下面是D
是我要投射到的通用对象的代码。 ObjectImplementation
是抽象层(因此在该类上使用的每个对象都实现该接口)。 SalesRepbyID
只是容器类的名称。 fileparser
是依赖项注入的另一部分(暂时忽略)。最后,解析是构造我需要投射的实例的方法。
我已经搜索了标题,并搜索了Stackoverflow结果以及外部网页。我认为我所缺少的称为工厂模式,但是我不确定如何实现这种事情,或者我是否处在正确的道路上。
这里的目标是使用反射和通用类型,以便可以在此容器类中构造实现ObjectImplementation
的任何类,并且可以通过属性文件而不是代码来更改要使用的实现。我在命名约定方面所做的任何愚蠢的事情,请让我知道,并一如既往地感谢您的努力。
public class SalesRepbyId<D extends ObjectImplementation> implements
DataParserImplementation<Map<String,D>> {
private FileParserImplementation<ArrayList<String[]>> FileParser;
public SalesRepbyId(FileParserImplementation<ArrayList<String[]>> FileParser){
this.FileParser = FileParser;
}
@Override
public Map<String, D> Parse() {
Properties prop = new Properties();
try {
prop.load(Data_Parser.class.getResourceAsStream("config.properties"));
} catch (IOException e) {
System.out.println(e + " error with config.properties I/O");
}
try {
Class<?> classToUse = Class.forName(prop.getProperty("ObjectImplementation"));
//construct classToUse instances here in the method many times with type D
答案 0 :(得分:0)
因此,在这种情况下,您可以做的是在构造Class<D>
时传递SalesRepById
:
class SalesRepById<D extends ...> {
private Class<D> typeOfD;
SalesRepById(..., Class<D> typeOfD) {
...
this.typeOfD = typeOfD;
}
@Override
public Map<String, D> parse() {
try {
Class<? extends D> typeFromFile =
Class.forName(...).asSubclass(typeOfD);
D instanceOfD =
typeFromFile.getConstructor().newInstance();
...
}
}
(请参阅Class.asSubclass
,它用于向下广播Class
实例。例如,如果我说Class<?> c = String.class;
,我可以说c.asSubclass(CharSequence.class)
以获得{{ 1}}。但是,Class<? extends CharSequence>
会引发异常。
这意味着您必须在编译时和构造对象时知道Integer.asSubclass(CharSequence.class)
的实际类型:
D
令我感到不安的是,您似乎在说SalesRepById<ActualType> srbid =
new SalesRepById<>(..., ActualType.class);
的实际类型是由文件指定的。在那种情况下,我认为您不应该为D
使用类型参数。看来您应该改用以下方式:
D
这仍然允许文件指定要使用的确切子类型,并且您不必在编译时就知道它。
通常,反射和泛型并不能很好地融合在一起。反射仅在运行时,而泛型仅在编译时。