Java 将未知反射类的类型更改为泛型类型 介绍
我正在我的代码中实现依赖注入 我已经到了配置了一个名为config.properties的属性文件的地步。我还知道如何将属性字符串反映到对象中 问题 问题是,当我做这个反射时,java说类型将是Java 将未知反射类的类型更改为泛型类型 介绍,java,generics,reflection,dependency-injection,type-conversion,Java,Generics,Reflection,Dependency Injection,Type Conversion,我正在我的代码中实现依赖注入 我已经到了配置了一个名为config.properties的属性文件的地步。我还知道如何将属性字符串反映到对象中 问题 问题是,当我做这个反射时,java说类型将是Class,我希望它是一个泛型类型D,这样我就可以重用与这个类耦合的代码 我在哪里 下面是代码,其中D是我想要强制转换到的通用对象ObjectImplementation是抽象层(因此该类上使用的每个对象都实现该接口)SalesRepbyID只是容器类的名称fileparser是依赖项注入的另一部分(暂时
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实现
数据解析实现{
私有文件解析器实现文件解析器;
public SalesRepbyId(FileParserImplementation FileParser){
this.FileParser=FileParser;
}
@凌驾
公共映射解析(){
Properties prop=新属性();
试一试{
load(Data_Parser.class.getResourceAsStream(“config.properties”);
}捕获(IOE异常){
System.out.println(e+“config.properties I/O错误”);
}
试一试{
Class classToUse=Class.forName(prop.getProperty(“ObjectImplementation”);
//在方法中多次使用类型D构造ClassUse实例
因此,在这种情况下,您可以在构建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();
...
}
}
让我感到紧张的是,您似乎在说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();
...
}
}
class SalesRepById{
SalesRepById(…){
...
}
@凌驾
公共映射解析(){
试一试{
ClassConcrete泛型类型参数在运行时被删除。因此,由于类在编译时不为人所知,您无法获得D
类型。您没有类型安全性,也无法获得它。所以我想的是错误的方法?错误的方法是指像错误的方法一样不完全实现我的目标。您不应该期望类型安全性。您仍然可以使用classToUse.newInstance().parseMethod()
(或任何方法名称)。但是D
是未知的,并且将保持未知。作为“配置”在应用程序中,您有可能重新设计代码,使配置提供某种枚举,在此基础上,您可以从编译时检查的内容中选择一个实现……您可以得到一个ClassIf I接受您的解决方案,那么任何实现ObjectImpl.并位于配置文件中的类都可以正常工作吗?我想需要D,这样我就可以创建泛型实例,这样任何以ObjectImpl为父类的类都可以在那里使用。只要我能做到这一点,我的问题就解决了。由于前面的评论+一些研究,我解决了我自己的问题,然后回来看到了这一点。由于我基本上做到了这一点,我接受它,因为它这很有帮助。
class SalesRepById {
SalesRepById(...) {
...
}
@Override
public Map<String, ObjectImplementation> parse() {
try {
Class<? extends ObjectImplementation> typeFromFile =
Class.forName(...).asSubclass(ObjectImplementation.class);
ObjectImplementation instance =
typeFromFile.getConstructor().newInstance();
...
}
}