(translation) Reflection-processing Java generics

Source: Internet
Author: User

When we declare a generic interface or class, or need a subclass to inherit to this generic class, we want to get these generic parameter information using reflection. This is the reflectionutil to be introduced in this article is to solve this kind of problem of the Auxiliary tool class, for the Java.lang.reflect Standard Library of the tool class. It provides a convenient way to access the reflection method of the Generic object type (Java.reflect.Type).

This article assumes that you have knowledge of Java reflection and can be used skillfully. If you don't understand Java reflection, then you can move on to the Oracel Reflex course, which may be a good starting point for you to start learning reflection.

The following features are included in the Reflectionutil:

    1. Gets the object class by type;
    2. Create objects by type;
    3. Gets the generic parameters of the generic object;
    4. Checks whether the object has a default constructor;
    5. Gets the specific field type in the specified type;
    6. Gets the specific method return type in the specified type;
    7. Gets the enumeration constants according to the string identifier;
    8. Reflectionutil.
Get object class by type
private static final String TYPE_NAME_PREFIX = "class ";public static String getClassName(Type type) {    if (type==null) {        return "";    }    String className = type.toString();    if (className.startsWith(TYPE_NAME_PREFIX)) {        className = className.substring(TYPE_NAME_PREFIX.length());    }    return className;}public static Class<?> getClass(Type type)             throws ClassNotFoundException {    String className = getClassName(type);    if (className==null || className.isEmpty()) {        return null;    }    return Class.forName(className);}

Method Reflectionutil#getclass (Type) implements the name of the Java.lang.Class object obtained from Java.lang.reflect.Type . Here, the ToString method of type is used to obtain the class of the type. such as "Class Some.package.Foo", take the latter part of the class name and use class.forname (String) to get the class object.

Create an object from type
public static Object newInstance(Type type)         throws ClassNotFoundException, InstantiationException, IllegalAccessException {    Class<?> clazz = getClass(type);    if (clazz==null) {        return null;    }    return clazz.newInstance();}

Method Reflectionutil#newinstance (Type type) constructs an object instance based on type. The type entered here cannot be an abstract class, an interface, an array type, and an underlying type, void otherwise a instantiationexception exception will occur.

Get generic parameters for generic objects

First, let's assume we have the following two objects:

public abstract class Foo<T> {    //content}public class FooChild extends Foo<Bar> {    

How do I get the generic class type that the subclass passed in Foo?

There are two common ways of doing this:

Forcing Foochild to pass in their own class type (which is also a more common practice):
public abstract class Foo<T> {    private Class<T> tClass;        public Foo(Class<T> tClass) {        this.tClass = tClass;    }    //content}public class FooChild extends Foo<Bar> {    public FooChild() {        super(FooChild.class);    }    
Using Reflection to get:
public static Type[] getParameterizedTypes(Object object) {    Type superclassType = object.getClass().getGenericSuperclass();    if (!ParameterizedType.class.isAssignableFrom(superclassType.getClass())) {        return null;    }    return ((ParameterizedType)superclassType).getActualTypeArguments();}

The Reflectionutil#getparameterizedtypes method uses reflection to get the type of the run-time generic parameter and returns the array. In this example, an array of type type T is returned.

To get the type of T for Foo We will use this method as follows:

...Type[] parameterizedTypes = ReflectionUtil.getParameterizedTypes(this);Class<T> clazz = (Class<T>)ReflectionUtil.getClass(parameterizedTypes[0]);...

Note :

In the documentation for Java.lang.reflect.parameterizedtype#getactualtypearguments () Documentation: you can see the following text:

in some cases, the returned array can be empty. This can occur. if this type represents a non-parameterized type nested within a parameterized type.

When an incoming object is a non-generic type, an empty array form is returned.

Checks whether the object has a default constructor
public static boolean hasDefaultConstructor(Class<?> clazz) throws SecurityException {    Class<?>[] empty = {};    try {        clazz.getConstructor(empty);    } catch (NoSuchMethodException e) {        return false;    }    return true;}

The Reflectionutil#hasdefaultconstructor method uses Java.lang.reflect.Constructor to check for the existence of a default parameterless constructor.

Gets the specific field type in the specified type

public static class<?> Getfieldclass (class<?> clazz, String name) {

if (clazz==null || name==null || name.isEmpty()) {    return null;}name = name.toLowerCase();Class<?> propertyClass = null;for (Field field : clazz.getDeclaredFields()) {    field.setAccessible(true);    if (field.getName().equals(name)) {        propertyClass = field.getType();        break;    }}return propertyClass;

}

In some cases you want to take advantage of known type information and specific field names to get the type of the field, then Reflectionutil#getfieldclass (CLASS<?> String) can help you. Reflectionutil#getfieldclass (CLASS<?> String) takes a field with Class#getdeclaredfields () and loops the comparison The Java.lang.reflect.field#getname () field name that returns the type object for the field.

Gets the specific method return type in the specified type
public static Class<?> getMethodReturnType(Class<?> clazz, String name) {    if (clazz==null || name==null || name.isEmpty()) {        return null;    }       name = name.toLowerCase();    Class<?> returnType = null;    for (Method method : clazz.getDeclaredMethods()) {        if (method.getName().equals(name)) {            returnType = method.getReturnType();            break;        }    }    return returnType;}

Method Reflectionutil#getmethodreturntype (CLASS<?> String) can help you get the method return type that corresponds to the object type and method name. Reflectionutil#getmethodreturntype (CLASS<?>, String) takes advantage of class#getdeclaredmethods () and Java.lang.reflect.method#getname () the method name, which returns the return value type of the Found method (Method#getreturntype ()).

Get enumeration constants based on string markers
@SuppressWarnings({ "unchecked", "rawtypes" })public static Object getEnumConstant(Class<?> clazz, String name) {    if (clazz==null || name==null || name.isEmpty()) {        return null;    }    return Enum.valueOf((Class<Enum>)clazz, name);}

Method Reflectionutil#getenumconstant (CLASS<?> String) gets its object with the enumerated type and enumeration name that is developed. The name here must match the enumerated constants that exist.

Reflectionutil

You can download Reflectionutil.java from here. Original English version address: http://qussay.com/2013/09/28/handling-java-generic-types-with-reflection/

(translation) Reflection-processing Java generics

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.