原理
JVM在运行时才动态加载类或者调用方法以及访问属性,不需要事先(比如编译时)知道运行对象是什么。
实现
1. 反射获取类实例 Class.forName(“xxx”);
首先调用了java.lang.Class的静态方法,获取类信息!
注意:forName()反射获取类信息,并没有将实现留给了java,而是交给了jvm去加载!
主要是先获取 ClassLoader, 然后调用 native 方法,获取信息,加载类则是回调 入参ClassLoader 进类加载!
@CallerSensitivepublic static Class<?> forName(String className) throws ClassNotFoundException {// 先通过反射,获取调用进来的类信息,从而获取当前的 classLoaderClass<?> caller = Reflection.getCallerClass();// 调用native方法进行获取class信息return forName0(className, true, ClassLoader.getClassLoader(caller), caller);}
2. ClassLoader 进类加载
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException{// 获取锁synchronized (getClassLoadingLock(name)) {// 如果已经加载了的话,就不用再加载了Class<?> c = findLoadedClass(name);if (c == null) {long t0 = System.nanoTime();try {// 双亲委托加载if (parent != null) {c = parent.loadClass(name, false);} else {c = findBootstrapClassOrNull(name);}} catch (ClassNotFoundException e) {// ClassNotFoundException thrown if class not found// from the non-null parent class loader}if (c == null) {// If still not found, then invoke findClass in order// to find the class.long t1 = System.nanoTime();c = findClass(name);// this is the defining class loader; record the statssun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);sun.misc.PerfCounter.getFindClasses().increment();}}if (resolve) {resolveClass(c);}return c;}}private final ConcurrentHashMap<String, Object> parallelLockMap;// 获取类加载锁protected Object getClassLoadingLock(String className) {Object lock = this;if (parallelLockMap != null) {Object newLock = new Object();// 使用 ConcurrentHashMap来保存锁lock = parallelLockMap.putIfAbsent(className, newLock);if (lock == null) {lock = newLock;}}return lock;}protected final Class<?> findLoadedClass(String name) {if (!checkName(name))return null;return findLoadedClass0(name);}private boolean checkName(String name) {if ((name == null) || (name.length() == 0))return true;if ((name.indexOf('/') != -1)|| (!VM.allowArraySyntax() && (name.charAt(0) == '[')))return false;return true;}private native final Class<?> findLoadedClass0(String name);
3. newInstance()
@CallerSensitivepublic T newInstance(Object ... initargs)throws InstantiationException, IllegalAccessException,IllegalArgumentException, InvocationTargetException{if (!override) {if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {Class<?> caller = Reflection.getCallerClass();checkAccess(caller, clazz, null, modifiers);}}if ((clazz.getModifiers() & Modifier.ENUM) != 0)throw new IllegalArgumentException("Cannot reflectively create enum objects");ConstructorAccessor ca = constructorAccessor;// read volatileif (ca == null) {ca = acquireConstructorAccessor();}@SuppressWarnings("unchecked")T inst = (T) ca.newInstance(initargs);return inst;}private volatile ConstructorAccessor constructorAccessor;
用处
- 实现自定义注解(AOP)
- 实现动态代理(DI)
- 可以访问一些私有变量和属性
