我问question
之间的差异public static <T> void work(Class<T> type, T instance);
和
public static <T, S extends T> void work(Class<T> type, S instance);
我想我应该解释一下我想知道什么。我想这次更新原始问题是不合适的,所以我在这里问另一个问题。
说,我想制作一个反映方法,用于调用Marshaller中定义的marshal
方法,例如
void marshal(Object element, ContentHandler handler)
void marshal(Object element, File output)
void marshal(Object element, Node node)
等等。
我正在研究的方法之一是
void marshal(Object jaxbElement, Class<?> targetType, Object target)
实施很简单
marshal(Ljava/lang/Object;Ljava/lang/Class;)V
和Object.class
targetType
的方法
element
和target
。因此任何单元测试代码都可以像
一样调用marshal(element, ContentHandler.class, handler);
marshal(element, File.class, new File("text.xml"));
在这种情况下,我应该如何定义marshal
方法?
<T> marshal(Object element, Class<T> targetType, T target);
和
<T, S extends T> marshal(Object element, Class<T> targetType, S target)
每个答案的进一步评论
我认为我需要targetType
来快速直接地查找正确的方法。
没有targetType
我必须迭代所有方法,如
for (Method method : Marshaller.class.getMethods()) {
// check modifiers, name, return type, and so on.
if (!method.getParameterTypes()[1].isAssignableFrom(target.getClass())) {
}
}
我想,为此添加另一个版本会更好。 :)
答案 0 :(得分:1)
如果您在T处分配课程,则无需在参数中提供课程,因此<T, S extends T> marshal(Object element, S target)
应该足够了。但由于S extends T
,S
可以被识别为T
。
除非您特别需要仅在类S
中的方法,否则可以省略它并写入
<T> marshal(Object element, T target)
但是,由于您正在创建泛型方法,因此您可能不需要声明S.这是由于以下原因:
如果S的方法与T不同,没有好的方法来确定几个不同类的S的方法。除非它们有一个共同的接口,但是你也可以使用公共接口作为{ {1}}。
如果S的方法没有区别,则没有理由将其明确指出为通用操作数。
答案 1 :(得分:1)
很难知道为什么要使用类对象,因为如果你有T
的实例,你可以在方法中执行此操作:
Class<T> targetType = target.getClass(); // class may be derived from the instance
但是,如果你真的需要通过课程,我想你想要这个:
<T> void marshal(Object element, Class<? super T> targetType, T target) {
}
通过使用Class<? super T>
,您可以灵活地传递一个Class,它是实例的超类而没有额外的泛型方法参数。
答案 2 :(得分:1)
的论证集没有区别
<T> marshal(Object element, Class<T> targetType, T target);
和
<T, S extends T> marshal(Object element, Class<T> targetType, S target)
可以接受。
因此,如果您正在编写API,则应该更喜欢更简单的API,即类型参数较少的API,即没有S
的那个。