get generic class type, default actual type argument index is 0. - Android java.lang.reflect

Android examples for java.lang.reflect:Class

Description

get generic class type, default actual type argument index is 0.

Demo Code


//package com.java2s;
import android.text.TextUtils;

import java.lang.reflect.Array;

import java.lang.reflect.GenericArrayType;

import java.lang.reflect.ParameterizedType;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public class Main {
    private static final ConcurrentMap<String, Class<?>> CLASS_CACHE = new ConcurrentHashMap<>();

    /**/*from   www. j  a v a  2  s  .c  o  m*/
     * get generic class type, default actual type argument index is 0.
     */
    public static Class<?> getGenericClass(Class<?> cls) {
        return getGenericClass(cls, 0);
    }

    /**
     * get generic class by actual type argument index.
     */
    public static Class<?> getGenericClass(Class<?> cls,
            int actualTypeArgIndex) {
        try {
            ParameterizedType parameterizedType;
            if (cls.getGenericInterfaces().length > 0
                    && cls.getGenericInterfaces()[0] instanceof ParameterizedType) {
                parameterizedType = ((ParameterizedType) cls
                        .getGenericInterfaces()[0]);
            } else if (cls.getGenericSuperclass() instanceof ParameterizedType) {
                parameterizedType = (ParameterizedType) cls
                        .getGenericSuperclass();
            } else {
                parameterizedType = null;
            }
            if (parameterizedType != null) {
                Object genericClass = parameterizedType
                        .getActualTypeArguments()[actualTypeArgIndex];
                if (genericClass instanceof ParameterizedType) {
                    return (Class<?>) ((ParameterizedType) genericClass)
                            .getRawType();
                } else if (genericClass instanceof GenericArrayType) {
                    Class<?> componentType = (Class<?>) ((GenericArrayType) genericClass)
                            .getGenericComponentType();
                    if (componentType.isArray()) {
                        return componentType;
                    } else {
                        return Array.newInstance(componentType, 0)
                                .getClass();
                    }
                } else if (genericClass instanceof Class) {
                    return (Class<?>) genericClass;
                }
            }
        } catch (Exception e) {
        }
        if (cls.getSuperclass() != null
                && cls.getSuperclass() != Object.class) {
            return getGenericClass(cls.getSuperclass(), actualTypeArgIndex);
        } else {
            throw new IllegalArgumentException(cls.getName()
                    + " generic type undefined!");
        }
    }

    /**
     * New instance for the given class name.{@link #forName(String)}
     *
     * @param className
     * @return
     */
    public static Object newInstance(String className) {
        try {
            return forName(className).newInstance();
        } catch (InstantiationException e) {
            throw new IllegalStateException(e.getMessage(), e);
        } catch (IllegalAccessException e) {
            throw new IllegalStateException(e.getMessage(), e);
        }
    }

    /**
     * Returns a {@code Class} object which represents the class with
     * the given name. The name should be the name of a non-primitive
     * class, as described in the {@link Class class definition}.
     * Primitive types can not be found using this method; use {@code
     * int.class} or {@code Integer.TYPE} instead.
     *
     * @param packages  class package
     * @param className given class name
     * @return
     */
    public static Class<?> forName(String[] packages, String className) {
        if (packages != null && packages.length > 0
                && !className.contains(".")
                && !CLASS_CACHE.containsKey(className)) {
            for (String pkg : packages) {
                try {
                    return _forName(pkg + "." + className);
                } catch (ClassNotFoundException e2) {
                }
            }
            try {
                return _forName("java.lang." + className);
            } catch (ClassNotFoundException e2) {
            }
        }
        try {
            return _forName(className);
        } catch (ClassNotFoundException e) {
            int index = className.lastIndexOf('.');
            if (index > 0 && index < className.length() - 1) {
                try {
                    return _forName(className.substring(0, index) + "$"
                            + className.substring(index + 1));
                } catch (ClassNotFoundException e2) {
                }
            }
            throw new IllegalStateException(e.getMessage(), e);
        }
    }

    /**
     * Returns a {@code Class} object which represents the class with
     * the given name. The name should be the name of a non-primitive
     * class, as described in the {@link Class class definition}.
     * Primitive types can not be found using this method; use {@code
     * int.class} or {@code Integer.TYPE} instead.
     *
     * @param className
     * @return
     */
    public static Class<?> forName(String className) {
        try {
            return _forName(className);
        } catch (ClassNotFoundException e) {
            throw new IllegalStateException(e.getMessage(), e);
        }
    }

    /**
     * Returns a {@code Class} object which represents the class with
     * the given name. The name should be the name of a non-primitive
     * class, as described in the {@link Class class definition}.
     * Primitive types can not be found using this method; use {@code
     * int.class} or {@code Integer.TYPE} instead.
     * <p/>
     * also support for array, like int[][].
     *
     * @param name
     * @return
     * @throws ClassNotFoundException
     */
    private static Class<?> _forName(String name)
            throws ClassNotFoundException {
        if (TextUtils.isEmpty(name)) {
            return null;
        }
        String key = name;
        Class<?> clazz = CLASS_CACHE.get(key);
        if (clazz == null) {
            int index = name.indexOf('[');
            if (index > 0) {
                int i = (name.length() - index) / 2;
                name = name.substring(0, index);
                StringBuilder sb = new StringBuilder();
                while (i-- > 0) {
                    sb.append("[");
                }
                if ("void".equals(name)) {
                    sb.append("V");
                } else if ("boolean".equals(name)) {
                    sb.append("Z");
                } else if ("byte".equals(name)) {
                    sb.append("B");
                } else if ("char".equals(name)) {
                    sb.append("C");
                } else if ("double".equals(name)) {
                    sb.append("D");
                } else if ("float".equals(name)) {
                    sb.append("F");
                } else if ("int".equals(name)) {
                    sb.append("I");
                } else if ("long".equals(name)) {
                    sb.append("J");
                } else if ("short".equals(name)) {
                    sb.append("S");
                } else {
                    sb.append('L').append(name).append(';');
                }
                name = sb.toString();
            }
            try {
                clazz = Class.forName(name, true, Thread.currentThread()
                        .getContextClassLoader());
            } catch (ClassNotFoundException cne) {
                clazz = Class.forName(name);
            }
            Class<?> old = CLASS_CACHE.putIfAbsent(key, clazz);
            if (old != null) {
                clazz = old;
            }
        }
        return clazz;
    }
}

Related Tutorials