简体   繁体   English

泛型类型声明以进行反射

[英]generics type declaration for reflection

I asked a question about differences between 我问一个问题,关于差异

public static <T> void work(Class<T> type, T instance);

and

public static <T, S extends T> void work(Class<T> type, S instance);

I think I should explain what exactly I want to know. 我想我应该解释我到底想知道什么。 Updating the original question is not proper for this time, I think, so I'm asking an another question here. 我认为目前不适合更新原始问题,因此我在这里提出另一个问题。

Say, I want to make a single reflected method for invoking those marshal methods defined in Marshaller such as 说,我想制作一个单一的反映方法来调用Marshaller中定义的那些marshal方法,例如

void marshal(Object element, ContentHandler handler)
void marshal(Object element, File output)
void marshal(Object element, Node node)

and so on. 等等。

One of method that I'm working on is 我正在研究的方法之一是

void marshal(Object jaxbElement, Class<?> targetType, Object target)

The implementation is simple 实现很简单

  1. Find a method looks like marshal(Ljava/lang/Object;Ljava/lang/Class;)V with Object.class and targetType 使用Object.classtargetType查找类似于marshal(Ljava/lang/Object;Ljava/lang/Class;)V
  2. invoke the method with element and target . elementtarget调用方法。

So any unit testing code can invoke like 所以任何单元测试代码都可以像

marshal(element, ContentHandler.class, handler);
marshal(element, File.class, new File("text.xml"));

In this case how should I define the marshal method? 在这种情况下,应该如何定义marshal方法? Is there any difference between 之间有什么区别

<T> marshal(Object element, Class<T> targetType, T target);

and

<T, S extends T> marshal(Object element, Class<T> targetType, S target)

?

Further Comments per Answers 每个答案的进一步评论

I think I need the targetType for fast and direct method looking the right method. 我认为我需要targetType用于快速和直接的方法来寻找正确的方法。

Without the targetType I have to iterate all methods like 没有targetType我必须迭代所有方法,例如

for (Method method : Marshaller.class.getMethods()) {

    // check modifiers, name, return type, and so on.

    if (!method.getParameterTypes()[1].isAssignableFrom(target.getClass())) {
    }
}

Adding another version for this will be better, I think. 我认为为此添加另一个版本会更好。 :) :)

If you assign the class at T, you don't need to feed it in the arguments, so <T, S extends T> marshal(Object element, S target) should be enough. 如果在T处分配该类,则无需在参数中提供它,因此<T, S extends T> marshal(Object element, S target)就足够了。 But since S extends T , S can be recognized as T . 但是由于S extends T ,所以S可以识别为T

Unless you specifically need methods that are only in class S , you can omit it and write 除非您特别需要仅在S类中使用的方法,否则可以省略并编写

<T> marshal(Object element, T target)

However, since you are creating a generic method, you probably won't need to declare S. This for the following reason: 但是,由于要创建泛型方法,因此可能不需要声明S。这是由于以下原因:

  • if the methods of S differ from T, there is no good way to determine the methods of several different classes of S. Unless they have a common interface, but then you might as well use the common interface as T . 如果S的方法不同于T,则没有好的方法来确定S的几个不同类的方法。除非它们具有公共接口,否则您最好将公共接口用作T

  • if the methods of S do not differ, there is not reason to specifically indicate it as generic operand. 如果S的方法没有不同,则没有理由将其专门表示为通用操作数。

It's hard to know why you want the class object, because if you have an instance of T you can do this in the method: 很难知道为什么要使用类对象,因为如果您有T的实例,则可以在方法中执行此操作:

Class<T> targetType = target.getClass(); // class may be derived from the instance    

However, if you really need to pass a class, I think you want this: 但是,如果您确实需要通过课程,我想您需要这样做:

<T> void marshal(Object element, Class<? super T> targetType, T target) {

}

By using Class<? super T> 通过使用Class<? super T> Class<? super T> you achieve the flexibility of passing a Class that is a super class of the instance without the extra generic method parameter. Class<? super T>您可以灵活地传递Class,该Class是实例的超类,而无需额外的泛型方法参数。

There is no difference in what sets of arguments that 哪些参数集没有区别

<T> marshal(Object element, Class<T> targetType, T target);

and

<T, S extends T> marshal(Object element, Class<T> targetType, S target)

can accept. 可以接受。

Therefore, if you are writing an API, you should prefer the simpler one, the one with fewer type parameters, ie the one without S . 因此,如果您正在编写API,则应该使用一种更简单的API,即类型参数较少的API,即不带S的API。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM