将 java.lang.reflect.Type 转换为 Class<T> clazz

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38761897/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 20:37:33  来源:igfitidea点击:

Convert java.lang.reflect.Type to Class<T> clazz

javagenerics

提问by Pau

How can I convert java.lang.reflect.Typeto Class<T> clazz?

我怎样才能转换java.lang.reflect.TypeClass<T> clazz

If I have one method as next which has an argument of Class<T>:

如果我有一个方法作为 next 其参数为Class<T>

public void oneMethod(Class<T> clazz) {     
    //Impl
}

Then another method which has an argument of java.lang.reflect.Typeand it calls oneMethod(Class<T> clazz)and for it I need to convert java.lang.reflect.Type typeto Class<T>:

然后另一个方法,它有一个参数,java.lang.reflect.Type它调用oneMethod(Class<T> clazz),为此我需要转换java.lang.reflect.Type typeClass<T>

public void someMehtod(java.lang.reflect.Type type) {
   // I want to pass type arg to other method converted in Class<T>
   otherMethod(?How to convert java.lang.reflect.Type to Class<T>?);
}

Is it possible?

是否可以?

采纳答案by Andy Turner

You have to ensure that typeis an instance of Class, and then cast it.

您必须确保它type是 的一个实例Class,然后对其进行转换。

if (type instanceof Class) {
  Class<?> clazz = (Class<?>) type;
  otherMethod(clazz);
}

Of course, you also have to handle the case of it not being a Class.

当然,您还必须处理它不是Class.

回答by Claudio Zesiger

Did you mean this?

你是这个意思吗?

public <T extends Type> void oneMethod(T clazz) {

}

public void someMethod(Type type) {
    oneMethod(type);
}

回答by Serge Ballesta

It would be weird that a Typewould be anything else than a Class... Javadoc for Typesays

奇怪的是,aType不是一个Class...... Javadoc forType

All Known Implementing Classes: Class

所有已知的实现类:类

So unless you have special libraries that use non ClassTypes, you can simply cast - but you must be ready for a possible ClassCastException. Beware: Java use undocumented Type implementation to represent generics, see below.

因此,除非您有使用 non ClassTypes 的特殊库,否则您可以简单地强制转换 - 但您必须准备好可能的ClassCastException. 注意:Java 使用未记录的 Type 实现来表示泛型,见下文。

You can explicitely process it or not because it is an unchecked exception:

您可以明确地处理它或不处理它,因为它是一个未经检查的异常:

Explicit way:

显式方式:

try {
    Class<?> clazz = (Class<?>) type;
}
catch (ClassCastException ex) {
    // process exception
}

Implicit way:

隐式方式:

Class<?> clazz = (Class<?>) type;

but the current method could throw...

但当前的方法可能会抛出......



EDIT per @Andy Turner's comment:

根据@Andy Turner 的评论编辑:

Beware: Type type = new ArrayList<String>().getClass().getGenericSuperclass();yields something that's a Type but not a Class. This one is a ParameterizedType, so you can use getRawType()method to find the actual class, but others might exist.

当心:Type type = new ArrayList<String>().getClass().getGenericSuperclass();产生的东西是类型而不是类。这是一个ParameterizedType,因此您可以使用getRawType()方法来查找实际类,但可能存在其他类。

回答by xonya

Andy Turner answer is correct, however if you need to retrieve a class from a type parameter this is a complete example:

Andy Turner 的回答是正确的,但是如果您需要从类型参数中检索一个类,这是一个完整的示例:

private static class MyClass extends ArrayList<Integer> {
}

public static void main(String[] args) {

    ParameterizedType arrayListWithParamType
            = (ParameterizedType) MyClass.class.getGenericSuperclass();

    Type integerType = arrayListWithParamType.getActualTypeArguments()[0];

    Class<?> integerClass = (Class<?>) integerType;

    System.out.println(integerClass == Integer.class);
}

回答by Daniel Beer

If you are willing to use a library, you could use com.google.guava:guava:12+:

如果您愿意使用图书馆,您可以使用com.google.guava:guava:12+

Class<?> clazz = com.google.common.reflect.TypeToken.of(type).getRawType();

Alternatively you could also use com.fasterxml.Hymanson.core:Hymanson-databind:2.8.x:

或者,您也可以使用com.fasterxml.Hymanson.core:Hymanson-databind:2.8.x

Class<?> clazz = com.fasterxml.Hymanson.databind.type.TypeFactory.rawClass(type);

This handles all cases correctly and you will get the type-erased class of your type.

这可以正确处理所有情况,您将获得类型擦除的类。

回答by virtuemaster

Using generic types in runtime is a little bit tricky in Java. And I think this is a root cause of your issue.

在运行时使用泛型类型在 Java 中有点棘手。我认为这是您问题的根本原因。

1) to be sure about generic in runtime we doing like this:

1)为了确保运行时的泛型,我们这样做:

class MyClass<E> {}

and then:

进而:

MyClass<TargetType> genericAwaredMyClassInctance = new MyClass<TargetType>(){};

please pay attention to {} in the end. It means anonymous extends of MyClass. This is an important nuance.

请注意{}到底。这意味着 MyClass 的匿名扩展。这是一个重要的细微差别。

2) let`s improve MyClass to be able to extract the type in runtime.

2) 让我们改进 MyClass 以便能够在运行时提取类型。

class MyClass<E> {

    @SuppressWarnings("unchecked")
    protected Class<E> getGenericClass() throws ClassNotFoundException {
        Type mySuperclass = getClass().getGenericSuperclass();
        Type tType = ((ParameterizedType)mySuperclass).getActualTypeArguments()[0];
        String className = tType.getTypeName();

        return (Class<E>) Class.forName(className);
    }

}

and finally, use it like this:

最后,像这样使用它:

MyClass<TargetType> genericAwaredMyClassInctance = new MyClass<TargetType>(){};

assert(genericAwaredMyClassInctance.getGenericClass() == TargetType.class)