Java tutorial
//package com.java2s; //License from project: Apache License 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<>(); /** * 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; } }