Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/397.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将未知反射类的类型更改为泛型类型 介绍_Java_Generics_Reflection_Dependency Injection_Type Conversion - Fatal编程技术网

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是依赖项注入的另一部分(暂时

我正在我的代码中实现依赖注入

我已经到了配置了一个名为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实现
数据解析实现{
私有文件解析器实现文件解析器;
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();

        ...
    }
}