一、前言
关于alibaba的dubbo源码包com.alibaba.dubbo.common.compiler.support.ClassUtils类工具类,实现对基本类型/对象类的实例化、基本类型boxed转换包装类及包装类unboxed转基本类型、获取getGenericClass指定接口泛型类型、获取getMethodName指定方法、查找指定方法类型searchMethod等方法处理,详情参见源码说明。
二、源码说明
package com.alibaba.dubbo.common.compiler.support;@b@@b@import java.io.PrintWriter;@b@import java.io.StringWriter;@b@import java.lang.reflect.Array;@b@import java.lang.reflect.GenericArrayType;@b@import java.lang.reflect.Method;@b@import java.lang.reflect.Modifier;@b@import java.lang.reflect.ParameterizedType;@b@import java.net.URI;@b@import java.net.URISyntaxException;@b@import java.util.Collection;@b@import java.util.HashMap;@b@import java.util.Map;@b@@b@/**@b@ * ClassUtils. (Tool, Static, ThreadSafe)@b@ */@b@public class ClassUtils {@b@@b@ public static final String CLASS_EXTENSION = ".class";@b@@b@ public static final String JAVA_EXTENSION = ".java";@b@ private static final int JIT_LIMIT = 5 * 1024;@b@@b@ private ClassUtils() {@b@ }@b@@b@ public static Object newInstance(String name) {@b@ try {@b@ return forName(name).newInstance();@b@ } catch (InstantiationException e) {@b@ throw new IllegalStateException(e.getMessage(), e);@b@ } catch (IllegalAccessException e) {@b@ throw new IllegalStateException(e.getMessage(), e);@b@ }@b@ }@b@@b@ public static Class<?> forName(String[] packages, String className) {@b@ try {@b@ return _forName(className);@b@ } catch (ClassNotFoundException e) {@b@ if (packages != null && packages.length > 0) {@b@ for (String pkg : packages) {@b@ try {@b@ return _forName(pkg + "." + className);@b@ } catch (ClassNotFoundException e2) {@b@ }@b@ }@b@ }@b@ throw new IllegalStateException(e.getMessage(), e);@b@ }@b@ }@b@@b@ public static Class<?> forName(String className) {@b@ try {@b@ return _forName(className);@b@ } catch (ClassNotFoundException e) {@b@ throw new IllegalStateException(e.getMessage(), e);@b@ }@b@ }@b@@b@ public static Class<?> _forName(String className) throws ClassNotFoundException {@b@ if ("boolean".equals(className))@b@ return boolean.class;@b@ if ("byte".equals(className))@b@ return byte.class;@b@ if ("char".equals(className))@b@ return char.class;@b@ if ("short".equals(className))@b@ return short.class;@b@ if ("int".equals(className))@b@ return int.class;@b@ if ("long".equals(className))@b@ return long.class;@b@ if ("float".equals(className))@b@ return float.class;@b@ if ("double".equals(className))@b@ return double.class;@b@ if ("boolean[]".equals(className))@b@ return boolean[].class;@b@ if ("byte[]".equals(className))@b@ return byte[].class;@b@ if ("char[]".equals(className))@b@ return char[].class;@b@ if ("short[]".equals(className))@b@ return short[].class;@b@ if ("int[]".equals(className))@b@ return int[].class;@b@ if ("long[]".equals(className))@b@ return long[].class;@b@ if ("float[]".equals(className))@b@ return float[].class;@b@ if ("double[]".equals(className))@b@ return double[].class;@b@ try {@b@ return arrayForName(className);@b@ } catch (ClassNotFoundException e) {@b@ // try to load from java.lang package@b@ if (className.indexOf('.') == -1) {@b@ try {@b@ return arrayForName("java.lang." + className);@b@ } catch (ClassNotFoundException e2) {@b@ // ignore, let the original exception be thrown@b@ }@b@ }@b@ throw e;@b@ }@b@ }@b@@b@ private static Class<?> arrayForName(String className) throws ClassNotFoundException {@b@ return Class.forName(className.endsWith("[]")@b@ ? "[L" + className.substring(0, className.length() - 2) + ";"@b@ : className, true, Thread.currentThread().getContextClassLoader());@b@ }@b@@b@ public static Class<?> getBoxedClass(Class<?> type) {@b@ if (type == boolean.class) {@b@ return Boolean.class;@b@ } else if (type == char.class) {@b@ return Character.class;@b@ } else if (type == byte.class) {@b@ return Byte.class;@b@ } else if (type == short.class) {@b@ return Short.class;@b@ } else if (type == int.class) {@b@ return Integer.class;@b@ } else if (type == long.class) {@b@ return Long.class;@b@ } else if (type == float.class) {@b@ return Float.class;@b@ } else if (type == double.class) {@b@ return Double.class;@b@ } else {@b@ return type;@b@ }@b@ }@b@@b@ public static Boolean boxed(boolean v) {@b@ return Boolean.valueOf(v);@b@ }@b@@b@ public static Character boxed(char v) {@b@ return Character.valueOf(v);@b@ }@b@@b@ public static Byte boxed(byte v) {@b@ return Byte.valueOf(v);@b@ }@b@@b@ public static Short boxed(short v) {@b@ return Short.valueOf(v);@b@ }@b@@b@ public static Integer boxed(int v) {@b@ return Integer.valueOf(v);@b@ }@b@@b@ public static Long boxed(long v) {@b@ return Long.valueOf(v);@b@ }@b@@b@ public static Float boxed(float v) {@b@ return Float.valueOf(v);@b@ }@b@@b@ public static Double boxed(double v) {@b@ return Double.valueOf(v);@b@ }@b@@b@ public static Object boxed(Object v) {@b@ return v;@b@ }@b@@b@ public static boolean unboxed(Boolean v) {@b@ return v == null ? false : v.booleanValue();@b@ }@b@@b@ public static char unboxed(Character v) {@b@ return v == null ? '\0' : v.charValue();@b@ }@b@@b@ public static byte unboxed(Byte v) {@b@ return v == null ? 0 : v.byteValue();@b@ }@b@@b@ public static short unboxed(Short v) {@b@ return v == null ? 0 : v.shortValue();@b@ }@b@@b@ public static int unboxed(Integer v) {@b@ return v == null ? 0 : v.intValue();@b@ }@b@@b@ public static long unboxed(Long v) {@b@ return v == null ? 0 : v.longValue();@b@ }@b@@b@ public static float unboxed(Float v) {@b@ return v == null ? 0 : v.floatValue();@b@ }@b@@b@ public static double unboxed(Double v) {@b@ return v == null ? 0 : v.doubleValue();@b@ }@b@@b@ public static Object unboxed(Object v) {@b@ return v;@b@ }@b@@b@ public static boolean isNotEmpty(Object object) {@b@ return getSize(object) > 0;@b@ }@b@@b@ public static int getSize(Object object) {@b@ if (object == null) {@b@ return 0;@b@ }@b@ if (object instanceof Collection<?>) {@b@ return ((Collection<?>) object).size();@b@ } else if (object instanceof Map<?, ?>) {@b@ return ((Map<?, ?>) object).size();@b@ } else if (object.getClass().isArray()) {@b@ return Array.getLength(object);@b@ } else {@b@ return -1;@b@ }@b@ }@b@@b@ public static URI toURI(String name) {@b@ try {@b@ return new URI(name);@b@ } catch (URISyntaxException e) {@b@ throw new RuntimeException(e);@b@ }@b@ }@b@@b@ public static Class<?> getGenericClass(Class<?> cls) {@b@ return getGenericClass(cls, 0);@b@ }@b@@b@ public static Class<?> getGenericClass(Class<?> cls, int i) {@b@ try {@b@ ParameterizedType parameterizedType = ((ParameterizedType) cls.getGenericInterfaces()[0]);@b@ Object genericClass = parameterizedType.getActualTypeArguments()[i];@b@ if (genericClass instanceof ParameterizedType) {@b@ return (Class<?>) ((ParameterizedType) genericClass).getRawType();@b@ } else if (genericClass instanceof GenericArrayType) {@b@ return (Class<?>) ((GenericArrayType) genericClass).getGenericComponentType();@b@ } else if (genericClass != null) {@b@ return (Class<?>) genericClass;@b@ }@b@ } catch (Throwable e) {@b@ }@b@ if (cls.getSuperclass() != null) {@b@ return getGenericClass(cls.getSuperclass(), i);@b@ } else {@b@ throw new IllegalArgumentException(cls.getName() + " generic type undefined!");@b@ }@b@ }@b@@b@ public static boolean isBeforeJava5(String javaVersion) {@b@ return (javaVersion == null || javaVersion.length() == 0 || "1.0".equals(javaVersion)@b@ || "1.1".equals(javaVersion) || "1.2".equals(javaVersion)@b@ || "1.3".equals(javaVersion) || "1.4".equals(javaVersion));@b@ }@b@@b@ public static boolean isBeforeJava6(String javaVersion) {@b@ return isBeforeJava5(javaVersion) || "1.5".equals(javaVersion);@b@ }@b@@b@ public static String toString(Throwable e) {@b@ StringWriter w = new StringWriter();@b@ PrintWriter p = new PrintWriter(w);@b@ p.print(e.getClass().getName() + ": ");@b@ if (e.getMessage() != null) {@b@ p.print(e.getMessage() + "\n");@b@ }@b@ p.println();@b@ try {@b@ e.printStackTrace(p);@b@ return w.toString();@b@ } finally {@b@ p.close();@b@ }@b@ }@b@@b@ public static void checkBytecode(String name, byte[] bytecode) {@b@ if (bytecode.length > JIT_LIMIT) {@b@ System.err.println("The template bytecode too long, may be affect the JIT compiler. template class: " + name);@b@ }@b@ }@b@@b@ public static String getSizeMethod(Class<?> cls) {@b@ try {@b@ return cls.getMethod("size", new Class<?>[0]).getName() + "()";@b@ } catch (NoSuchMethodException e) {@b@ try {@b@ return cls.getMethod("length", new Class<?>[0]).getName() + "()";@b@ } catch (NoSuchMethodException e2) {@b@ try {@b@ return cls.getMethod("getSize", new Class<?>[0]).getName() + "()";@b@ } catch (NoSuchMethodException e3) {@b@ try {@b@ return cls.getMethod("getLength", new Class<?>[0]).getName() + "()";@b@ } catch (NoSuchMethodException e4) {@b@ return null;@b@ }@b@ }@b@ }@b@ }@b@ }@b@@b@ public static String getMethodName(Method method, Class<?>[] parameterClasses, String rightCode) {@b@ if (method.getParameterTypes().length > parameterClasses.length) {@b@ Class<?>[] types = method.getParameterTypes();@b@ StringBuilder buf = new StringBuilder(rightCode);@b@ for (int i = parameterClasses.length; i < types.length; i++) {@b@ if (buf.length() > 0) {@b@ buf.append(",");@b@ }@b@ Class<?> type = types[i];@b@ String def;@b@ if (type == boolean.class) {@b@ def = "false";@b@ } else if (type == char.class) {@b@ def = "\'\\0\'";@b@ } else if (type == byte.class@b@ || type == short.class@b@ || type == int.class@b@ || type == long.class@b@ || type == float.class@b@ || type == double.class) {@b@ def = "0";@b@ } else {@b@ def = "null";@b@ }@b@ buf.append(def);@b@ }@b@ }@b@ return method.getName() + "(" + rightCode + ")";@b@ }@b@@b@ public static Method searchMethod(Class<?> currentClass, String name, Class<?>[] parameterTypes) throws NoSuchMethodException {@b@ if (currentClass == null) {@b@ throw new NoSuchMethodException("class == null");@b@ }@b@ try {@b@ return currentClass.getMethod(name, parameterTypes);@b@ } catch (NoSuchMethodException e) {@b@ for (Method method : currentClass.getMethods()) {@b@ if (method.getName().equals(name)@b@ && parameterTypes.length == method.getParameterTypes().length@b@ && Modifier.isPublic(method.getModifiers())) {@b@ if (parameterTypes.length > 0) {@b@ Class<?>[] types = method.getParameterTypes();@b@ boolean match = true;@b@ for (int i = 0; i < parameterTypes.length; i++) {@b@ if (!types[i].isAssignableFrom(parameterTypes[i])) {@b@ match = false;@b@ break;@b@ }@b@ }@b@ if (!match) {@b@ continue;@b@ }@b@ }@b@ return method;@b@ }@b@ }@b@ throw e;@b@ }@b@ }@b@@b@ public static String getInitCode(Class<?> type) {@b@ if (byte.class.equals(type)@b@ || short.class.equals(type)@b@ || int.class.equals(type)@b@ || long.class.equals(type)@b@ || float.class.equals(type)@b@ || double.class.equals(type)) {@b@ return "0";@b@ } else if (char.class.equals(type)) {@b@ return "'\\0'";@b@ } else if (boolean.class.equals(type)) {@b@ return "false";@b@ } else {@b@ return "null";@b@ }@b@ }@b@@b@ public static <K, V> Map<K, V> toMap(Map.Entry<K, V>[] entries) {@b@ Map<K, V> map = new HashMap<K, V>();@b@ if (entries != null && entries.length > 0) {@b@ for (Map.Entry<K, V> enrty : entries) {@b@ map.put(enrty.getKey(), enrty.getValue());@b@ }@b@ }@b@ return map;@b@ }@b@@b@}