Java 使用原始类型为反射的子类动态应用类型参数 重要:

Java 使用原始类型为反射的子类动态应用类型参数 重要:,java,generics,reflection,interface,raw-types,Java,Generics,Reflection,Interface,Raw Types,我目前拥有的代码符合我的期望。它做了我想让它做的事。我的问题是我的工作方式是否错误。我问这个问题的原因是因为我看到了大量关于原始类型的堆栈溢出结果,以及它们基本上不应该被使用的方式 我在做什么以及为什么我使用原始类型 目前,我正在动态地创建一个泛型接口的具体子类,当类被构造时,接口将在其中接受参数。当我创建这个类的一个实例并使用它返回的对象调用各种方法时,我使用原始类型,因为它适用于我试图做的事情。下面是我的功能代码中使用原始类型的示例。此代码是自上而下的顺序,即代码块之间没有代码 加载属性文件

我目前拥有的代码符合我的期望。它做了我想让它做的事。我的问题是我的工作方式是否错误。我问这个问题的原因是因为我看到了大量关于原始类型的堆栈溢出结果,以及它们基本上不应该被使用的方式

我在做什么以及为什么我使用原始类型 目前,我正在动态地创建一个泛型接口的具体子类,当类被构造时,接口将在其中接受参数。当我创建这个类的一个实例并使用它返回的对象调用各种方法时,我使用原始类型,因为它适用于我试图做的事情。下面是我的功能代码中使用原始类型的示例。此代码是自上而下的顺序,即代码块之间没有代码

加载属性文件

Properties prop = new Properties();
    try {
    prop.load(ObjectFactory.class.getResourceAsStream("config.properties"));
这是实现
FileParserImplementation
的文件解析器,它接收数据并将其放入数组中。此代码获取类类型,然后动态生成该类型的实例

Class<? extends FileParserImplementation> parser = null;
parser = Class.forName(prop.getProperty("FileParserImplementation")).asSubclass(FileParserImplementation.class);
FileParserImplementation ParserInstance = (FileParserImplementation) parser.getDeclaredConstructors()[0].newInstance();
这是实现
crossreferenceimplementation
Crossreferencer
类。它接收这两个数据集,并以实际的具体反射类所希望的任何方式交叉引用它们。这也可以在运行时配置。它在此主菜单中输出一个地图。 地图作为数据的最终集合(稍后我可能会更改)

请注意,每次我以反射方式创建实现某个接口的类的实例时,我都将该接口用作原始类型。我希望反射在创建具体的子类时能够看到这个原始类型的参数化类型,因为参数类型实际上是在这个子类中指定的。关键是让实现这些接口的任何类都是泛型的,它们可以接受任何东西,并返回任何东西

我尽量不使用原始类型的东西。 我试图在反射的
crossreferencer
类中实际获取
交叉引用实现的参数化类型,我现在通过调用

Class arrayparametertype = (Class)((ParameterizedType)crossreferencer.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
然后在创建
交叉引用器的实例时,我尝试传入
数组参数
,如下所示:

CrossReferenceImplementation crossReferencer = (CrossReferenceImplementation<<arrayparametertype>>) crossreferencer.getDeclaredConstructors()[0].newInstance();
指定映射结果的实际参数化类型时,错误消息为: “
crossReferencer
具有原始类型,因此
CrossReference
的结果将被擦除”

运行代码确实为我确认了
.CrossReference
方法的结果被删除,而其他一切都正常运行

在这里问之前,我尝试了哪些互联网搜索 因此,我使用了两个操作的原始类型,如主代码所示,所有操作都正常工作。但我看到了很多“不要使用原始类型”。这就是为什么我要问:这是对原始类型的适当使用吗?我应该用另一种不破坏反射的方式吗?它破坏了反射,因为手动指定类型参数不仅使代码无法运行,还意味着只能使用具体的类。我进行了反思,以便可以使用实现通用接口的任何东西。我不想只使用具体的实例。我尝试过在堆栈溢出中搜索我的标题和其他类似的内容。我认为这可能与类型擦除有关,但我真的不确定。没有其他东西真正解决这个问题,因为没有任何东西同时讨论泛型、参数化类型和反射(我的问题的关键)。我被告知泛型和反射不能很好地结合在一起,但这段代码无论如何都能正常工作,并且按照我希望的方式工作。它工作得很好。我只是想确定我没有做错什么

进球。 了解我目前对原始类型的使用情况,以便我知道我的做法是正确的。我所说的“正确”是指与下面我定义的“错误”相反的方式。我寻求的“理解”的一个例子是:

要了解puesdo代码为何遵循以下内容:

ConcreteClass forname(myPropertiesFileObject.get(ConcreteClassname)) as subClass of (MyGenericInterface);
MyRAWGenericInterfaceType ConcreteClassInstance = (MyRAWGenericInterfaceType) ConcreteClass.newInstance( Insert generic Type constructor arguments here);
RAWCollectionType someCollection = RAWCollectionType concreteClassInstance.CallingAMethod(Insert generic Type method arguments here);
使用原始类型,其中接口或集合类型名称中包含
Raw
。这与以某种不使用原始类型但不打破反射点的方式来解耦这些类之间的交互相反。在这种情况下,使用硬代码指定参数将“破坏反射”。此外,我想了解为什么在上面的pusedocode中为这些
RAW
类型指定参数(即使我知道这不是我要做的)会导致上面问题中列出的错误,也就是说,当向方法返回的
RAWCollectionType
提供实际参数时,为什么
调用方法的结果会被删除?根本问题是,当我在声明时向
RAWCollectionType
提供类型参数时,它拒绝被
CallingAMethod
返回的内容更新,我不明白为什么。它接受返回值,但是如果方法
CallingAMethod
的主体将返回值作为参数传入,在方法内部更新,然后返回,则我收到的返回没有更新<在本例中,code>CallingAMethod
的列表如下:

[1,2,3]
在这个方法中,我有这样的想法:

foreach(thing in list){
    thing += 1
}
然后我返回了列表,在指定参数时得到的返回值是[1,2,3],在使用原始类型时得到的返回值是[2,3,4]。我问这个是因为我听说过使用原始类型的不好的事情

此外,我希望确保我对原始类型的使用没有严重错误,并且它能够正常工作,因为它应该正常工作。也许我刚刚在整个反射和泛型方面做得很好,并且找到了原始类型的有效用法,或者我可能正在做一些非常可怕的事情
//how the parameters were specified. Messy and breaks the reflection.
CrossReferenceImplementation<Map<String, SalesRep>,Map<String, SalesRep>,Map<String, SalesRep>> crossReferencer = (CrossReferenceImplementation) crossreferencer.getDeclaredConstructors()[0].newInstance();

//where the warning occured
Map reflectiveFinalMap = (Map) crossReferencer.CrossReference(Dataset1.Parse(), Dataset2.Parse());
//where the parameterized type was specified
Map reflectiveFinalMap = (Map<String,SalesRep>) crossReferencer.CrossReference(Dataset1.Parse(), Dataset2.Parse());
ConcreteClass forname(myPropertiesFileObject.get(ConcreteClassname)) as subClass of (MyGenericInterface);
MyRAWGenericInterfaceType ConcreteClassInstance = (MyRAWGenericInterfaceType) ConcreteClass.newInstance( Insert generic Type constructor arguments here);
RAWCollectionType someCollection = RAWCollectionType concreteClassInstance.CallingAMethod(Insert generic Type method arguments here);
[1,2,3]
foreach(thing in list){
    thing += 1
}
public class FieldAccessor<O, T> { 
    final Field field; // + private constructor
    public T get(O object) { return (T) field.get(object); } // unsafe, bu we validated this before constructing this accessor
    public static <O, T> FieldAccessor<O, T> create(Class<? super O> definingClass, Class<? super T> fieldClass, String fieldName) {
        Field field = definingClass.getDeclaredField(fieldName);
        if (field.getType() != fieldClass) {
            throw some exception;
        }
        return new FieldAccessor<>(field);
    }
FieldAccessor<X, A> keyAccessor = FieldAccessor.create(X.class, A.class, "someProperty");
FieldAccessor<Y, B> valueAccessor = FieldAccessor.create(Y.class, B.class, "someOtherProperty");
Map<A, B> myMap = new HashMap<>();
mapMap.put(keyAccessor.get(myXValue), valueAccessor.get(myYValue));