简介
我正在我的代码中实现依赖注入。
我已经到了配置一个名为config.properties的属性文件的地步。我还知道如何将属性字符串反映到对象中。
问题所在
问题是,当我做这个反射时,java说这个类型将是Class<?>
的,我希望它是一个泛型类型D
这样我就可以重用与这个类耦合的代码。
我在哪里
下面是代码,其中D
是我要强制转换为的通用对象。ObjectImplementation
是抽象层(因此在此类上使用的每个对象都实现了该接口(。SalesRepbyID
只是容器类的名称。fileparser
是依赖注入的不同部分(暂时忽略它(。最后,Parse 是构造我需要强制转换的实例的方法。
我已经用谷歌搜索了标题,并搜索了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
因此,在这种情况下,您可以做的是在构造SalesRepById
时传递Class<D>
:
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)
以获得Class<? extends CharSequence>
。但是,Integer.asSubclass(CharSequence.class)
会引发异常。
这意味着您必须在编译时和对象构造时知道D
的实际类型:
SalesRepById<ActualType> srbid =
new SalesRepById<>(..., ActualType.class);
让我紧张的是,您似乎在说文件指定了D
的实际类型。在这种情况下,我认为您不应该有D
的类型参数。似乎您应该改用这样的东西:
class SalesRepById {
SalesRepById(...) {
...
}
@Override
public Map<String, ObjectImplementation> parse() {
try {
Class<? extends ObjectImplementation> typeFromFile =
Class.forName(...).asSubclass(ObjectImplementation.class);
ObjectImplementation instance =
typeFromFile.getConstructor().newInstance();
...
}
}
这仍然允许文件指定要使用的确切子类型,并且您不必在编译时知道它。
作为一般规则,反射和泛型不能很好地混合。反射是仅运行时的,泛型是仅编译时的。