У меня есть метод, похожий на этот.Как получить <? super T> от T
static <T> void doSomethind(final Class<? super T> type, final T instance) {
}
И есть способ поиска соответствующего суперкласса для T или Object.
static Class<?> getType(final Object instance) {
// returns a Class which is parent of given instance.
}
Я даже не уверен, что <? super T>
часть необходимо или нет. Может это <T>
?
static void doSomething(final Object instance) {
final Class<?> type = getType(instance);
// how can I call <T>doSomething(Class<T>, t)?
}
Или
static <T> void doSomething(final T instance) {
final Class<?> type = getType(instance);
// how can I call <T>doSomething(Class<T>, t)?
}
Вопрос в том, как я могу назвать doSomething(Class, Object)
метод?
UPDATE
мне так жаль. Но я даже не знаю, что я прошу. Поэтому я решил рассказать глупую (полную) историю.
В javax.xml.bind.Marshaller, есть способы выглядеть marshal(Object, XXX)
, такие как
- маршала (Object, ContentHandler)
- маршала (Object, File)
- и так далее.
И я думал, что могу сделать общий метод утилиты, используя отражение, подобное этому.
public static <T> marshal(Marshaller marshaller, Object element,
Class<? super T> targetType, T target)
throws VariousNastyExceptions {
// like a boss, huh?
Marshaller.class.getMethod("marshal", Object.class, targetType)
.invoke(marshaller, element, target);
}
// still not sure about <? super T>
Так что каждый может ссылаться именно так.
marshal(marshaller, element, OutputStream.class, output);
// say output is an instance of ByteArrayOutputStream
marshal(marshaller, element, Result.class, result);
// say the result is an instance of StreamResult
А потом я хочу новую версию без targetType
.
Для этого я, во-первых, собрал этих кандидатов для targetType
.
// InputStream.class, File.class, XMLEventWriter.class, and so on.
static final List<Class<?>> TARGET_TYPES;
static {
final List<Class<?>> targetTypes = new ArrayList<Class<?>>();
for (Method method : Marshaller.class.getMethods()) {
// if method is for marshal(Object, T) // code skipped
targetTypes.add(method.getParameterTypes()[0]);
}
TARGET_TYPES = Collections.unmodifiableList(targetTypes);
}
Теперь я могу принести targetType
от данного Object
.
static Class<?> getTargetType(Object target) {
for (Class<?> targetType : TARGET_TYPES) {
if (targetType.isAssignableFrom(target.getClass())) {
return targetType;
}
}
return null; // don't count this for now
}
И я, наконец, попытался
// do I need a <T> here?
static void marshal(Marshaller marshaller, Object element, Object target) {
final Class<?> targetType = getTargetType(target);
// compiler hates this statement
marshal(marshaller, element, targetType, target);
}
Я просто хочу Cipher
для дешифрования следующего сообщения.
method Marshallers.<T> marshal(Marshaller,Object,Class<? super T>, T) is not applicable
(actual argument Class <CAP#1> cannot be converted to Class<? super Object> by method
invocation conversion)
Я думаю, что смогу это сделать.
static <T> void marshal(Marshaller marshaller, Object element, T target) {
// No ClassCastException guaranteed
@SuppressWarnings("unchecked")
final Class<? super T> targetType =
(Class<? super T>) getTargetType(target);
marshal(marshaller, element, targetType, target);
}
Есть ли лучший способ?
Я не думаю, что есть лучший способ. При объединении «продвинутых» дженериков с Reflection вы можете быть счастливы, что он работает вообще. ;) – ssindelar
Я даже не знаю, какой ответ я должен принять. Тем не менее все проголосовали. –