一、前言
关于spark包(spark-master)的spark.utils.ClassUtils类工具类对类转换、类加载器、类的实例化加载等进行操作,详情见源码说明。
二、源码说明
package spark.utils;import java.lang.reflect.Array;import java.util.Arrays;import java.util.HashMap;import java.util.HashSet;import java.util.Map;import java.util.Set; public abstract class ClassUtils { public static final String ARRAY_SUFFIX = "[]"; private static final String INTERNAL_ARRAY_PREFIX = "["; private static final String NON_PRIMITIVE_ARRAY_PREFIX = "[L"; private static final Map<Class<?>, Class<?>> primitiveWrapperTypeMap = new HashMap<>(8); private static final Map<Class<?>, Class<?>> primitiveTypeToWrapperMap = new HashMap<>(8); private static final Map<String, Class<?>> primitiveTypeNameMap = new HashMap<>(32); private static final Map<String, Class<?>> commonClassCache = new HashMap<>(32); 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()); registerCommonClasses(entry.getKey()); } Set<Class<?>> primitiveTypes = new HashSet<>(32); primitiveTypes.addAll(primitiveWrapperTypeMap.values()); primitiveTypes.addAll(Arrays.asList(new Class<?>[] { boolean[].class, byte[].class, char[].class, double[].class, float[].class, int[].class, long[].class, short[].class})); primitiveTypes.add(void.class); for (Class<?> primitiveType : primitiveTypes) { primitiveTypeNameMap.put(primitiveType.getName(), primitiveType); } registerCommonClasses(Boolean[].class, Byte[].class, Character[].class, Double[].class, Float[].class, Integer[].class, Long[].class, Short[].class); registerCommonClasses(Number.class, Number[].class, String.class, String[].class, Object.class, Object[].class, Class.class, Class[].class); registerCommonClasses(Throwable.class, Exception.class, RuntimeException.class, Error.class, StackTraceElement.class, StackTraceElement[].class); } private static void registerCommonClasses(Class<?>... commonClasses) { for (Class<?> clazz : commonClasses) { commonClassCache.put(clazz.getName(), clazz); } } public static ClassLoader getDefaultClassLoader() { ClassLoader cl = null; try { cl = Thread.currentThread().getContextClassLoader(); } catch (Throwable ex) { // Cannot access thread context ClassLoader - falling back to system class loader... } if (cl == null) { // No thread context class loader -> use class loader of this class. cl = ClassUtils.class.getClassLoader(); } return cl; } public static Class<?> forName(String name, ClassLoader classLoader) throws ClassNotFoundException, LinkageError { Assert.notNull(name, "Name must not be null"); Class<?> clazz = resolvePrimitiveClassName(name); if (clazz == null) { clazz = commonClassCache.get(name); } if (clazz != null) { return clazz; } // "java.lang.String[]" style arrays if (name.endsWith(ARRAY_SUFFIX)) { String elementClassName = name.substring(0, name.length() - ARRAY_SUFFIX.length()); Class<?> elementClass = forName(elementClassName, classLoader); return Array.newInstance(elementClass, 0).getClass(); } // "[Ljava.lang.String;" style arrays if (name.startsWith(NON_PRIMITIVE_ARRAY_PREFIX) && name.endsWith(";")) { String elementName = name.substring(NON_PRIMITIVE_ARRAY_PREFIX.length(), name.length() - 1); Class<?> elementClass = forName(elementName, classLoader); return Array.newInstance(elementClass, 0).getClass(); } // "[[I" or "[[Ljava.lang.String;" style arrays if (name.startsWith(INTERNAL_ARRAY_PREFIX)) { String elementName = name.substring(INTERNAL_ARRAY_PREFIX.length()); Class<?> elementClass = forName(elementName, classLoader); return Array.newInstance(elementClass, 0).getClass(); } ClassLoader classLoaderToUse = classLoader; if (classLoaderToUse == null) { classLoaderToUse = getDefaultClassLoader(); } try { return classLoaderToUse.loadClass(name); } catch (ClassNotFoundException ex) { int lastDotIndex = name.lastIndexOf('.'); if (lastDotIndex != -1) { String innerClassName = name.substring(0, lastDotIndex) + '$' + name.substring(lastDotIndex + 1); try { return classLoaderToUse.loadClass(innerClassName); } catch (ClassNotFoundException ex2) { // swallow - let original exception get through } } throw ex; } } public static Class<?> resolvePrimitiveClassName(String name) { Class<?> result = null; // Most class names will be quite long, considering that they // SHOULD sit in a package, so a length check is worthwhile. if (name != null && name.length() <= 8) { // Could be a primitive - likely. result = primitiveTypeNameMap.get(name); } return result; } public static String classPackageAsResourcePath(Class<?> clazz) { if (clazz == null) { return ""; } String className = clazz.getName(); int packageEndIndex = className.lastIndexOf('.'); if (packageEndIndex == -1) { return ""; } String packageName = className.substring(0, packageEndIndex); return packageName.replace('.', '/'); }}