/* * Copyright 2011-2013 HTTL Team. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.github.lazylibrary.util; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.GenericArrayType; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.math.BigDecimal; import java.math.BigInteger; import java.net.URI; import java.net.URISyntaxException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; /** * ClassUtils. (Tool, Static, ThreadSafe) * * @author Liang Fei (liangfei0201 AT gmail DOT com) */ public class ClassUtils { public static final String CLASS_EXTENSION = ".class"; public static final String JAVA_EXTENSION = ".java"; private static final ConcurrentMap<Class<?>, Map<String, Method>> GETTER_CACHE = new ConcurrentHashMap<Class<?>, Map<String, Method>>(); private static final ConcurrentMap<String, Class<?>> CLASS_CACHE = new ConcurrentHashMap<String, Class<?>>(); static { CLASS_CACHE.put("boolean", boolean.class); CLASS_CACHE.put("char", char.class); CLASS_CACHE.put("byte", byte.class); CLASS_CACHE.put("short", short.class); CLASS_CACHE.put("int", int.class); CLASS_CACHE.put("long", long.class); CLASS_CACHE.put("float", float.class); CLASS_CACHE.put("double", double.class); CLASS_CACHE.put("void", void.class); CLASS_CACHE.put("Boolean", Boolean.class); CLASS_CACHE.put("Character", Character.class); CLASS_CACHE.put("Byte", Byte.class); CLASS_CACHE.put("Short", Short.class); CLASS_CACHE.put("Integer", Integer.class); CLASS_CACHE.put("Long", Long.class); CLASS_CACHE.put("Float", Float.class); CLASS_CACHE.put("Double", Double.class); CLASS_CACHE.put("Number", Number.class); CLASS_CACHE.put("String", String.class); CLASS_CACHE.put("Object", Object.class); CLASS_CACHE.put("Class", Class.class); CLASS_CACHE.put("Void", Void.class); CLASS_CACHE.put("java.lang.Boolean", Boolean.class); CLASS_CACHE.put("java.lang.Character", Character.class); CLASS_CACHE.put("java.lang.Byte", Byte.class); CLASS_CACHE.put("java.lang.Short", Short.class); CLASS_CACHE.put("java.lang.Integer", Integer.class); CLASS_CACHE.put("java.lang.Long", Long.class); CLASS_CACHE.put("java.lang.Float", Float.class); CLASS_CACHE.put("java.lang.Double", Double.class); CLASS_CACHE.put("java.lang.Number", Number.class); CLASS_CACHE.put("java.lang.String", String.class); CLASS_CACHE.put("java.lang.Object", Object.class); CLASS_CACHE.put("java.lang.Class", Class.class); CLASS_CACHE.put("java.lang.Void", Void.class); CLASS_CACHE.put("java.util.Date", Date.class); CLASS_CACHE.put("boolean[]", boolean[].class); CLASS_CACHE.put("char[]", char[].class); CLASS_CACHE.put("byte[]", byte[].class); CLASS_CACHE.put("short[]", short[].class); CLASS_CACHE.put("int[]", int[].class); CLASS_CACHE.put("long[]", long[].class); CLASS_CACHE.put("float[]", float[].class); CLASS_CACHE.put("double[]", double[].class); CLASS_CACHE.put("Boolean[]", Boolean[].class); CLASS_CACHE.put("Character[]", Character[].class); CLASS_CACHE.put("Byte[]", Byte[].class); CLASS_CACHE.put("Short[]", Short[].class); CLASS_CACHE.put("Integer[]", Integer[].class); CLASS_CACHE.put("Long[]", Long[].class); CLASS_CACHE.put("Float[]", Float[].class); CLASS_CACHE.put("Double[]", Double[].class); CLASS_CACHE.put("Number[]", Number[].class); CLASS_CACHE.put("String[]", String[].class); CLASS_CACHE.put("Object[]", Object[].class); CLASS_CACHE.put("Class[]", Class[].class); CLASS_CACHE.put("Void[]", Void[].class); CLASS_CACHE.put("java.lang.Boolean[]", Boolean[].class); CLASS_CACHE.put("java.lang.Character[]", Character[].class); CLASS_CACHE.put("java.lang.Byte[]", Byte[].class); CLASS_CACHE.put("java.lang.Short[]", Short[].class); CLASS_CACHE.put("java.lang.Integer[]", Integer[].class); CLASS_CACHE.put("java.lang.Long[]", Long[].class); CLASS_CACHE.put("java.lang.Float[]", Float[].class); CLASS_CACHE.put("java.lang.Double[]", Double[].class); CLASS_CACHE.put("java.lang.Number[]", Number[].class); CLASS_CACHE.put("java.lang.String[]", String[].class); CLASS_CACHE.put("java.lang.Object[]", Object[].class); CLASS_CACHE.put("java.lang.Class[]", Class[].class); CLASS_CACHE.put("java.lang.Void[]", Void[].class); CLASS_CACHE.put("java.util.Date[]", Date[].class); } public static Object newInstance(String name) { try { return forName(name).newInstance(); } catch (InstantiationException e) { throw new IllegalStateException(e.getMessage(), e); } catch (IllegalAccessException e) { throw new IllegalStateException(e.getMessage(), e); } } public static Class<?> forName(String[] packages, String className) { // import class 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) { // inner class int i = className.lastIndexOf('.'); if (i > 0 && i < className.length() - 1) { try { return _forName(className.substring(0, i) + "$" + className.substring(i + 1)); } catch (ClassNotFoundException e2) { } } throw new IllegalStateException(e.getMessage(), e); } } public static Class<?> forName(String className) { try { return _forName(className); } catch (ClassNotFoundException e) { throw new IllegalStateException(e.getMessage(), e); } } private static Class<?> _forName(String name) throws ClassNotFoundException { if (StringUtils.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("["); // int[][] } 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; } public static Class<?> getUnboxedClass(Class<?> type) { if (type == Boolean.class) { return boolean.class; } else if (type == Character.class) { return char.class; } else if (type == Byte.class) { return byte.class; } else if (type == Short.class) { return short.class; } else if (type == Integer.class) { return int.class; } else if (type == Long.class) { return long.class; } else if (type == Float.class) { return float.class; } else if (type == Double.class) { return double.class; } else { return type; } } public static Class<?> getBoxedClass(Class<?> type) { if (type == boolean.class) { return Boolean.class; } else if (type == char.class) { return Character.class; } else if (type == byte.class) { return Byte.class; } else if (type == short.class) { return Short.class; } else if (type == int.class) { return Integer.class; } else if (type == long.class) { return Long.class; } else if (type == float.class) { return Float.class; } else if (type == double.class) { return Double.class; } else { return type; } } public static Boolean boxed(boolean v) { return Boolean.valueOf(v); } public static Character boxed(char v) { return Character.valueOf(v); } public static Byte boxed(byte v) { return Byte.valueOf(v); } public static Short boxed(short v) { return Short.valueOf(v); } public static Integer boxed(int v) { return Integer.valueOf(v); } public static Long boxed(long v) { return Long.valueOf(v); } public static Float boxed(float v) { return Float.valueOf(v); } public static Double boxed(double v) { return Double.valueOf(v); } public static <T> T boxed(T v) { return v; } public static boolean unboxed(Boolean v) { return v == null ? false : v.booleanValue(); } public static char unboxed(Character v) { return v == null ? '\0' : v.charValue(); } public static byte unboxed(Byte v) { return v == null ? 0 : v.byteValue(); } public static short unboxed(Short v) { return v == null ? 0 : v.shortValue(); } public static int unboxed(Integer v) { return v == null ? 0 : v.intValue(); } public static long unboxed(Long v) { return v == null ? 0 : v.longValue(); } public static float unboxed(Float v) { return v == null ? 0 : v.floatValue(); } public static double unboxed(Double v) { return v == null ? 0 : v.doubleValue(); } public static <T> T unboxed(T v) { return v; } public static boolean isTrue(boolean object) { return object; } public static boolean isTrue(char object) { return object != '\0'; } public static boolean isTrue(byte object) { return object != (byte) 0; } public static boolean isTrue(short object) { return object != (short) 0; } public static boolean isTrue(int object) { return object != 0; } public static boolean isTrue(long object) { return object != 0l; } public static boolean isTrue(float object) { return object != 0f; } public static boolean isTrue(double object) { return object != 0d; } public static boolean isTrue(Object object) { if (object instanceof Boolean) { return ((Boolean) object).booleanValue(); } return getSize(object) != 0; } public static boolean isNotEmpty(Object object) { return isTrue(object); } public static int getSize(Object object) { if (object == null) { return 0; } else if (object instanceof Collection<?>) { return ((Collection<?>) object).size(); } else if (object instanceof Map<?, ?>) { return ((Map<?, ?>) object).size(); } else if (object instanceof Object[]) { return ((Object[]) object).length; } else if (object instanceof int[]) { return ((int[]) object).length; } else if (object instanceof long[]) { return ((long[]) object).length; } else if (object instanceof float[]) { return ((float[]) object).length; } else if (object instanceof double[]) { return ((double[]) object).length; } else if (object instanceof short[]) { return ((short[]) object).length; } else if (object instanceof byte[]) { return ((byte[]) object).length; } else if (object instanceof char[]) { return ((char[]) object).length; } else if (object instanceof boolean[]) { return ((boolean[]) object).length; } else { return -1; } } public static URI toURI(String name) { try { return new URI(name); } catch (URISyntaxException e) { throw new RuntimeException(e); } } public static String getMethodFullName(String name, Class<?>[] parameterTypes) { StringBuilder buf = new StringBuilder(); buf.append(name); buf.append("("); if (parameterTypes != null && parameterTypes.length > 0) { boolean first = true; for (Class<?> type : parameterTypes) { if (type != null) { if (first) { first = false; } else { buf.append(","); } buf.append(type.getCanonicalName()); } } } buf.append(")"); return buf.toString(); } public static Class<?> getGenericClass(Class<?> cls) { return getGenericClass(cls, 0); } public static Class<?> getGenericClass(Class<?> cls, int i) { 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()[i]; 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(), i); } else { throw new IllegalArgumentException( cls.getName() + " generic type undefined!"); } } public static String getJavaVersion() { return System.getProperty("java.specification.version"); } public static boolean isBeforeJava5(String javaVersion) { return (StringUtils.isEmpty(javaVersion) || "1.0".equals(javaVersion) || "1.1".equals(javaVersion) || "1.2".equals(javaVersion) || "1.3".equals(javaVersion) || "1.4".equals(javaVersion)); } public static boolean isBeforeJava6(String javaVersion) { return isBeforeJava5(javaVersion) || "1.5".equals(javaVersion); } public static String toString(Throwable e) { StringWriter w = new StringWriter(); PrintWriter p = new PrintWriter(w); p.print(e.getClass().getName() + ": "); if (e.getMessage() != null) { p.print(e.getMessage() + "\n"); } p.println(); try { e.printStackTrace(p); return w.toString(); } finally { p.close(); } } private static final int JIT_LIMIT = 5 * 1024; public static void checkBytecode(String name, byte[] bytecode) { if (bytecode.length > JIT_LIMIT) { System.err.println( "The template bytecode too long, may be affect the JIT compiler. template class: " + name); } } public static String getSizeMethod(Class<?> cls, String[] sizers) { for (String sizer : sizers) { try { return cls.getMethod(sizer, new Class<?>[0]).getName() + "()"; } catch (NoSuchMethodException e) { } } return null; } public static String getMethodName(Method method, Class<?>[] parameterClasses, String rightCode) { if (method.getParameterTypes().length > parameterClasses.length) { Class<?>[] types = method.getParameterTypes(); StringBuilder buf = new StringBuilder(rightCode); for (int i = parameterClasses.length; i < types.length; i++) { if (buf.length() > 0) { buf.append(","); } Class<?> type = types[i]; String def; if (type == boolean.class) { def = "false"; } else if (type == char.class) { def = "\'\\0\'"; } else if (type == byte.class || type == short.class || type == int.class || type == long.class || type == float.class || type == double.class) { def = "0"; } else { def = "null"; } buf.append(def); } } return method.getName() + "(" + rightCode + ")"; } @SuppressWarnings("unchecked") public static Object searchProperty(Object leftParameter, String name) throws Exception { Class<?> leftClass = leftParameter.getClass(); Object result; if (leftParameter.getClass().isArray() && "length".equals(name)) { result = Array.getLength(leftParameter); } else if (leftParameter instanceof Map) { result = ((Map<Object, Object>) leftParameter).get(name); } else { try { String getter = "get" + name.substring(0, 1).toUpperCase() + name.substring(1); Method method = leftClass.getMethod(getter, new Class<?>[0]); if (!method.isAccessible()) { method.setAccessible(true); } result = method.invoke(leftParameter, new Object[0]); } catch (NoSuchMethodException e2) { try { String getter = "is" + name.substring(0, 1).toUpperCase() + name.substring(1); Method method = leftClass.getMethod(getter, new Class<?>[0]); if (!method.isAccessible()) { method.setAccessible(true); } result = method.invoke(leftParameter, new Object[0]); } catch (NoSuchMethodException e3) { Field field = leftClass.getField(name); result = field.get(leftParameter); } } } return result; } public static Method searchMethod(Class<?> currentClass, String name, Class<?>[] parameterTypes) throws NoSuchMethodException { return searchMethod(currentClass, name, parameterTypes, false); } public static Method searchMethod(Class<?> currentClass, String name, Class<?>[] parameterTypes, boolean boxed) throws NoSuchMethodException { if (currentClass == null) { throw new NoSuchMethodException("class == null"); } try { return currentClass.getMethod(name, parameterTypes); } catch (NoSuchMethodException e) { Method likeMethod = null; for (Method method : currentClass.getMethods()) { if (method.getName().equals(name) && parameterTypes.length == method.getParameterTypes().length && Modifier.isPublic(method.getModifiers())) { if (parameterTypes.length > 0) { Class<?>[] types = method.getParameterTypes(); boolean eq = true; boolean like = true; for (int i = 0; i < parameterTypes.length; i++) { Class<?> type = types[i]; Class<?> parameterType = parameterTypes[i]; if (type != null && parameterType != null && !type.equals(parameterType)) { eq = false; if (boxed) { type = ClassUtils.getBoxedClass(type); parameterType = ClassUtils.getBoxedClass( parameterType); } if (!type.isAssignableFrom(parameterType)) { eq = false; like = false; break; } } } if (!eq) { if (like && (likeMethod == null || likeMethod.getParameterTypes()[0].isAssignableFrom( method.getParameterTypes()[0]))) { likeMethod = method; } continue; } } return method; } } if (likeMethod != null) { return likeMethod; } throw e; } } public static String getInitCode(Class<?> type) { if (byte.class.equals(type) || short.class.equals(type) || int.class.equals(type) || long.class.equals(type) || float.class.equals(type) || double.class.equals(type)) { return "0"; } else if (char.class.equals(type)) { return "'\\0'"; } else if (boolean.class.equals(type)) { return "false"; } else { return "null"; } } public static String getInitCodeWithType(Class<?> type) { if (byte.class.equals(type)) { return "(byte) 0"; } else if (short.class.equals(type)) { return "(short) 0"; } else if (int.class.equals(type)) { return "0"; } else if (long.class.equals(type)) { return "0l"; } else if (float.class.equals(type)) { return "0f"; } else if (double.class.equals(type)) { return "0d"; } else if (char.class.equals(type)) { return "'\\0'"; } else if (boolean.class.equals(type)) { return "false"; } else { return "(" + type.getCanonicalName() + ") null"; } } public static boolean toBoolean(Object value) { if (value instanceof Boolean) { return (Boolean) value; } return value == null ? false : toBoolean(String.valueOf(value)); } public static char toChar(Object value) { if (value instanceof Character) { return (Character) value; } return value == null ? '\0' : toChar(String.valueOf(value)); } public static byte toByte(Object value) { if (value instanceof Number) { return ((Number) value).byteValue(); } return value == null ? 0 : toByte(String.valueOf(value)); } public static short toShort(Object value) { if (value instanceof Number) { return ((Number) value).shortValue(); } return value == null ? 0 : toShort(String.valueOf(value)); } public static int toInt(Object value) { if (value instanceof Number) { return ((Number) value).intValue(); } return value == null ? 0 : toInt(String.valueOf(value)); } public static long toLong(Object value) { if (value instanceof Number) { return ((Number) value).longValue(); } return value == null ? 0 : toLong(String.valueOf(value)); } public static float toFloat(Object value) { if (value instanceof Number) { return ((Number) value).floatValue(); } return value == null ? 0 : toFloat(String.valueOf(value)); } public static double toDouble(Object value) { if (value instanceof Number) { return ((Number) value).doubleValue(); } return value == null ? 0 : toDouble(String.valueOf(value)); } public static Class<?> toClass(Object value) { if (value instanceof Class) { return (Class<?>) value; } return value == null ? null : toClass(String.valueOf(value)); } public static boolean toBoolean(String value) { return StringUtils.isEmpty(value) ? false : Boolean.parseBoolean(value); } public static char toChar(String value) { return StringUtils.isEmpty(value) ? '\0' : value.charAt(0); } public static byte toByte(String value) { return StringUtils.isEmpty(value) ? 0 : Byte.parseByte(value); } public static short toShort(String value) { return StringUtils.isEmpty(value) ? 0 : Short.parseShort(value); } public static int toInt(String value) { return StringUtils.isEmpty(value) ? 0 : Integer.parseInt(value); } public static long toLong(String value) { return StringUtils.isEmpty(value) ? 0 : Long.parseLong(value); } public static float toFloat(String value) { return StringUtils.isEmpty(value) ? 0 : Float.parseFloat(value); } public static double toDouble(String value) { return StringUtils.isEmpty(value) ? 0 : Double.parseDouble(value); } public static Class<?> toClass(String value) { return StringUtils.isEmpty(value) ? null : ClassUtils.forName(value); } public static Method getGetter(Object bean, String property) { Map<String, Method> cache = GETTER_CACHE.get(bean.getClass()); if (cache == null) { cache = new ConcurrentHashMap<String, Method>(); for (Method method : bean.getClass().getMethods()) { if (Modifier.isPublic(method.getModifiers()) && !Modifier.isStatic(method.getModifiers()) && !void.class.equals(method.getReturnType()) && method.getParameterTypes().length == 0) { String name = method.getName(); if (name.length() > 3 && name.startsWith("get")) { cache.put(name.substring(3, 4).toLowerCase() + name.substring(4), method); } else if (name.length() > 2 && name.startsWith("is")) { cache.put(name.substring(2, 3).toLowerCase() + name.substring(3), method); } } } Map<String, Method> old = GETTER_CACHE.putIfAbsent(bean.getClass(), cache); if (old != null) { cache = old; } } return cache.get(property); } public static Object getProperty(Object bean, String property) { if (bean == null || StringUtils.isEmpty(property)) { return null; } try { Method getter = getGetter(bean, property); if (getter != null) { if (!getter.isAccessible()) { getter.setAccessible(true); } return getter.invoke(bean, new Object[0]); } return null; } catch (Exception e) { return null; } } public static void setProperties(Object bean, Map<String, Object> properties) { for (Method method : bean.getClass().getMethods()) { String name = method.getName(); if (name.length() > 3 && name.startsWith("set") && Modifier.isPublic(method.getModifiers()) && method.getParameterTypes().length == 1 && method.getDeclaringClass() != Object.class) { String key = name.substring(3, 4).toLowerCase() + name.substring(4); try { Object value = properties.get(key); if (value != null) { method.invoke(bean, new Object[] { convertCompatibleType(value, method.getParameterTypes()[0]) }); } } catch (Exception e) { } } } } public static Map<String, Object> getProperties(Object bean) { Map<String, Object> map = new HashMap<String, Object>(); for (Method method : bean.getClass().getMethods()) { String name = method.getName(); if ((name.length() > 3 && name.startsWith("get") || name.length() > 2 && name.startsWith("is")) && Modifier.isPublic(method.getModifiers()) && method.getParameterTypes().length == 0 && method.getDeclaringClass() != Object.class) { int i = name.startsWith("get") ? 3 : 2; String key = name.substring(i, i + 1).toLowerCase() + name.substring(i + 1); try { map.put(key, method.invoke(bean, new Object[0])); } catch (Exception e) { } } } return map; } public static <K, V> Set<Map.Entry<K, V>> entrySet(Map<K, V> map) { return map == null ? null : map.entrySet(); } public static String dumpException(Throwable e) { StringWriter sw = new StringWriter(160); sw.write(e.getClass().getName()); sw.write(":\n"); e.printStackTrace(new PrintWriter(sw)); return sw.toString(); } public static String filterJavaKeyword(String name) { if ("abstract".equals(name) || "assert".equals(name) || "boolean".equals(name) || "break".equals(name) || "byte".equals(name) || "case".equals(name) || "catch".equals(name) || "char".equals(name) || "class".equals(name) || "continue".equals(name) || "default".equals(name) || "do".equals(name) || "double".equals(name) || "else".equals(name) || "enum".equals(name) || "extends".equals(name) || "final".equals(name) || "finally".equals(name) || "float".equals(name) || "for".equals(name) || "if".equals(name) || "implements".equals(name) || "import".equals(name) || "instanceof".equals(name) || "int".equals(name) || "interface".equals(name) || "long".equals(name) || "native".equals(name) || "new".equals(name) || "package".equals(name) || "private".equals(name) || "protected".equals(name) || "public".equals(name) || "return".equals(name) || "strictfp".equals(name) || "short".equals(name) || "static".equals(name) || "super".equals(name) || "switch".equals(name) || "synchronized".equals(name) || "this".equals(name) || "throw".equals(name) || "throws".equals(name) || "transient".equals(name) || "try".equals(name) || "void".equals(name) || "volatile".equals(name) || "while".equals(name)) { return "$" + name; } return name; } private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; /** * 兼容类型转换。null值是OK的。如果不需要转换,则返回原来的值。 * 进行的兼容类型转换如下:(基本类对应的Wrapper类型不再列出。) * @param value 转换的类型 * @param type 字节码 * @return 返回转换之后的对象 */ @SuppressWarnings({ "unchecked", "rawtypes" }) public static Object convertCompatibleType(Object value, Class<?> type) { if (value == null || type == null || type.isAssignableFrom(value.getClass())) { return value; } if (value instanceof String) { String string = (String) value; if (char.class.equals(type) || Character.class.equals(type)) { if (string.length() != 1) { throw new IllegalArgumentException(String.format( "CAN NOT convert String(%s) to char!" + " when convert String to char, the String MUST only 1 char.", string)); } return string.charAt(0); } else if (type.isEnum()) { return Enum.valueOf((Class<Enum>) type, string); } else if (type == BigInteger.class) { return new BigInteger(string); } else if (type == BigDecimal.class) { return new BigDecimal(string); } else if (type == Short.class || type == short.class) { return new Short(string); } else if (type == Integer.class || type == int.class) { return new Integer(string); } else if (type == Long.class || type == long.class) { return new Long(string); } else if (type == Double.class || type == double.class) { return new Double(string); } else if (type == Float.class || type == float.class) { return new Float(string); } else if (type == Byte.class || type == byte.class) { return new Byte(string); } else if (type == Boolean.class || type == boolean.class) { return new Boolean(string); } else if (type == Date.class) { try { return new SimpleDateFormat(DATE_FORMAT).parse( (String) value); } catch (ParseException e) { throw new IllegalStateException( "Failed to parse date " + value + " by format " + DATE_FORMAT + ", cause: " + e.getMessage(), e); } } else if (type == Class.class) { return ClassUtils.forName((String) value); } } else if (value instanceof Number) { Number number = (Number) value; if (type == byte.class || type == Byte.class) { return number.byteValue(); } else if (type == short.class || type == Short.class) { return number.shortValue(); } else if (type == int.class || type == Integer.class) { return number.intValue(); } else if (type == long.class || type == Long.class) { return number.longValue(); } else if (type == float.class || type == Float.class) { return number.floatValue(); } else if (type == double.class || type == Double.class) { return number.doubleValue(); } else if (type == BigInteger.class) { return BigInteger.valueOf(number.longValue()); } else if (type == BigDecimal.class) { return BigDecimal.valueOf(number.doubleValue()); } else if (type == Date.class) { return new Date(number.longValue()); } } else if (value instanceof Collection) { Collection collection = (Collection) value; if (type.isArray()) { int length = collection.size(); Object array = Array.newInstance(type.getComponentType(), length); int i = 0; for (Object item : collection) { Array.set(array, i++, item); } return array; } else if (!type.isInterface()) { try { Collection result = (Collection) type.newInstance(); result.addAll(collection); return result; } catch (Throwable e) { } } else if (type == List.class) { return new ArrayList<Object>(collection); } else if (type == Set.class) { return new HashSet<Object>(collection); } } else if (value.getClass().isArray() && Collection.class.isAssignableFrom(type)) { Collection collection; if (!type.isInterface()) { try { collection = (Collection) type.newInstance(); } catch (Throwable e) { collection = new ArrayList<Object>(); } } else if (type == Set.class) { collection = new HashSet<Object>(); } else { collection = new ArrayList<Object>(); } int length = Array.getLength(value); for (int i = 0; i < length; i++) { collection.add(Array.get(value, i)); } return collection; } return value; } private ClassUtils() {} }