package com.guang.netty.transfer.util;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
/**
* 有关 <code>Class</code> 处理的工具类。
*
* <p>
* 这个类中的每个方法都可以“安全”地处理 <code>null</code> ,而不会抛出
* <code>NullPointerException</code>。
* </p>
*
* @author <a href="mailto:
[email protected]">saga67</a>
* @version create on 2011-5-17 下午03:31:11
*/
public class ClassUtil {
/*
* ==========================================================================
* ==
*/
/* 常量和singleton。 */
/*
* ==========================================================================
* ==
*/
/** 资源文件的分隔符: <code>'/'</code>。 */
public static final char RESOURCE_SEPARATOR_CHAR = '/';
/** Java类名的分隔符: <code>'.'</code>。 */
public static final char PACKAGE_SEPARATOR_CHAR = '.';
/** Java类名的分隔符: <code>"."</code>。 */
public static final String PACKAGE_SEPARATOR = String
.valueOf(PACKAGE_SEPARATOR_CHAR);
/** 内联类的分隔符: <code>'$'</code>。 */
public static final char INNER_CLASS_SEPARATOR_CHAR = '$';
/** 内联类的分隔符: <code>"$"</code>。 */
public static final String INNER_CLASS_SEPARATOR = String
.valueOf(INNER_CLASS_SEPARATOR_CHAR);
/** 所有类的信息表,包括父类, 接口, 数组的维数等信息。 */
private static Map<Class<?>, TypeInfo> TYPE_MAP = Collections
.synchronizedMap(new WeakHashMap<Class<?>, TypeInfo>());
private static final Map<Class<?>, Class<?>> primitiveWrapperTypeMap = new HashMap<Class<?>, Class<?>>(
8);
private static final Map<Class<?>, Class<?>> primitiveTypeToWrapperMap = new HashMap<Class<?>, Class<?>>(
8);
private ClassUtil() {
}
static {
primitiveWrapperTypeMap.put(Boolean.class, boolean.class);
primitiveWrapperTypeMap.put(Byte.class, byte.class);
primitiveWrapperTypeMap.put(Character.class, char.class);
primitiveWrapperTypeMap.put(Double.class, double.class);
primitiveWrapperTypeMap.put(Float.class, float.class);
primitiveWrapperTypeMap.put(Integer.class, int.class);
primitiveWrapperTypeMap.put(Long.class, long.class);
primitiveWrapperTypeMap.put(Short.class, short.class);
for (Map.Entry<Class<?>, Class<?>> entry : primitiveWrapperTypeMap
.entrySet()) {
primitiveTypeToWrapperMap.put(entry.getValue(), entry.getKey());
}
}
/*
* ==========================================================================
* ==
*/
/* 取得类名和package名的方法。 */
/*
* ==========================================================================
* ==
*/
/**
* 取得对象所属的类的直观类名。
*
* <p>
* 相当于 <code>object.getClass().getName()</code> ,但不同的是,该方法用更直观的方式显示数组类型。 例如:
*
* <pre>
* int[].class.getName() = "[I" ClassUtil.getClassName(int[].class) = "int[]"
*
* Integer[][].class.getName() = "[[Ljava.lang.Integer;" ClassUtil.getClassName(Integer[][].class) = "java.lang.Integer[][]"
* </pre>
*
* </p>
*
* <p>
* 对于非数组的类型,该方法等效于 <code>Class.getName()</code> 方法。
* </p>
*
* <p>
* 注意,该方法所返回的数组类名只能用于显示给人看,不能用于 <code>Class.forName</code> 操作。
* </p>
*
* @param object
* 要显示类名的对象
*
* @return 用于显示的直观类名,如果原类名为空或非法,则返回 <code>null</code>
*/
public static String getClassNameForObject(Object object) {
if (object == null) {
return null;
}
return getClassName(object.getClass().getName(), true);
}
/**
* 取得直观的类名。
*
* <p>
* 相当于 <code>clazz.getName()</code> ,但不同的是,该方法用更直观的方式显示数组类型。 例如:
*
* <pre>
* int[].class.getName() = "[I" ClassUtil.getClassName(int[].class) = "int[]"
*
* Integer[][].class.getName() = "[[Ljava.lang.Integer;" ClassUtil.getClassName(Integer[][].class) = "java.lang.Integer[][]"
* </pre>
*
* </p>
*
* <p>
* 对于非数组的类型,该方法等效于 <code>Class.getName()</code> 方法。
* </p>
*
* <p>
* 注意,该方法所返回的数组类名只能用于显示给人看,不能用于 <code>Class.forName</code> 操作。
* </p>
*
* @param clazz
* 要显示类名的类
*
* @return 用于显示的直观类名,如果原始类为 <code>null</code> ,则返回 <code>null</code>
*/
public static String getClassName(Class<?> clazz) {
if (clazz == null) {
return null;
}
return getClassName(clazz.getName(), true);
}
/**
* 取得直观的类名。
*
* <p>
* <code>className</code> 必须是从 <code>clazz.getName()</code>
* 所返回的合法类名。该方法用更直观的方式显示数组类型。 例如:
*
* <pre>
* int[].class.getName() = "[I" ClassUtil.getClassName(int[].class) = "int[]"
*
* Integer[][].class.getName() = "[[Ljava.lang.Integer;" ClassUtil.getClassName(Integer[][].class) = "java.lang.Integer[][]"
* </pre>
*
* </p>
*
* <p>
* 对于非数组的类型,该方法等效于 <code>Class.getName()</code> 方法。
* </p>
*
* <p>
* 注意,该方法所返回的数组类名只能用于显示给人看,不能用于 <code>Class.forName</code> 操作。
* </p>
*
* @param className
* 要显示的类名
*
* @return 用于显示的直观类名,如果原类名为 <code>null</code> ,则返回 <code>null</code>
* ,如果原类名是非法的,则返回原类名
*/
public static String getClassName(String className) {
return getClassName(className, true);
}
/**
* 取得直观的类名。
*
* @param className
* 类名
* @param processInnerClass
* 是否将内联类分隔符 <code>'$'</code> 转换成 <code>'.'</code>
*
* @return 直观的类名,或 <code>null</code>
*/
private static String getClassName(String className,
boolean processInnerClass) {
if (StringUtil.isEmpty(className)) {
return className;
}
if (processInnerClass) {
className = className.replace(INNER_CLASS_SEPARATOR_CHAR,
PACKAGE_SEPARATOR_CHAR);
}
int length = className.length();
int dimension = 0;
// 取得数组的维数,如果不是数组,维数为0
for (int i = 0; i < length; i++, dimension++) {
if (className.charAt(i) != '[') {
break;
}
}
// 如果不是数组,则直接返回
if (dimension == 0) {
return className;
}
// 确保类名合法
if (length <= dimension) {
return className; // 非法类名
}
// 处理数组
StringBuilder componentTypeName = new StringBuilder();
switch (className.charAt(dimension)) {
case 'Z':
componentTypeName.append("boolean");
break;
case 'B':
componentTypeName.append("byte");
break;
case 'C':
componentTypeName.append("char");
break;
case 'D':
componentTypeName.append("double");
break;
case 'F':
componentTypeName.append("float");
break;
case 'I':
componentTypeName.append("int");
break;
case 'J':
componentTypeName.append("long");
break;
case 'S':
componentTypeName.append("short");
break;
case 'L':
if ((className.charAt(length - 1) != ';')
|| (length <= (dimension + 2))) {
return className; // 非法类名
}
componentTypeName.append(className.substring(dimension + 1,
length - 1));
break;
default:
return className; // 非法类名
}
for (int i = 0; i < dimension