原理

JVM在运行时才动态加载类或者调用方法以及访问属性,不需要事先(比如编译时)知道运行对象是什么。

实现

1. 反射获取类实例 Class.forName(“xxx”);

首先调用了java.lang.Class的静态方法,获取类信息!
注意:forName()反射获取类信息,并没有将实现留给了java,而是交给了jvm去加载!
主要是先获取 ClassLoader, 然后调用 native 方法,获取信息,加载类则是回调 入参ClassLoader 进类加载!

  1. @CallerSensitive
  2. public static Class<?> forName(String className) throws ClassNotFoundException {
  3. // 先通过反射,获取调用进来的类信息,从而获取当前的 classLoader
  4. Class<?> caller = Reflection.getCallerClass();
  5. // 调用native方法进行获取class信息
  6. return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
  7. }

2. ClassLoader 进类加载

  1. protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
  2. {
  3. // 获取锁
  4. synchronized (getClassLoadingLock(name)) {
  5. // 如果已经加载了的话,就不用再加载了
  6. Class<?> c = findLoadedClass(name);
  7. if (c == null) {
  8. long t0 = System.nanoTime();
  9. try {
  10. // 双亲委托加载
  11. if (parent != null) {
  12. c = parent.loadClass(name, false);
  13. } else {
  14. c = findBootstrapClassOrNull(name);
  15. }
  16. } catch (ClassNotFoundException e) {
  17. // ClassNotFoundException thrown if class not found
  18. // from the non-null parent class loader
  19. }
  20. if (c == null) {
  21. // If still not found, then invoke findClass in order
  22. // to find the class.
  23. long t1 = System.nanoTime();
  24. c = findClass(name);
  25. // this is the defining class loader; record the stats
  26. sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
  27. sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
  28. sun.misc.PerfCounter.getFindClasses().increment();
  29. }
  30. }
  31. if (resolve) {
  32. resolveClass(c);
  33. }
  34. return c;
  35. }
  36. }
  37. private final ConcurrentHashMap<String, Object> parallelLockMap;
  38. // 获取类加载锁
  39. protected Object getClassLoadingLock(String className) {
  40. Object lock = this;
  41. if (parallelLockMap != null) {
  42. Object newLock = new Object();
  43. // 使用 ConcurrentHashMap来保存锁
  44. lock = parallelLockMap.putIfAbsent(className, newLock);
  45. if (lock == null) {
  46. lock = newLock;
  47. }
  48. }
  49. return lock;
  50. }
  51. protected final Class<?> findLoadedClass(String name) {
  52. if (!checkName(name))
  53. return null;
  54. return findLoadedClass0(name);
  55. }
  56. private boolean checkName(String name) {
  57. if ((name == null) || (name.length() == 0))
  58. return true;
  59. if ((name.indexOf('/') != -1)
  60. || (!VM.allowArraySyntax() && (name.charAt(0) == '[')))
  61. return false;
  62. return true;
  63. }
  64. private native final Class<?> findLoadedClass0(String name);

3. newInstance()

  1. @CallerSensitive
  2. public T newInstance(Object ... initargs)
  3. throws InstantiationException, IllegalAccessException,IllegalArgumentException, InvocationTargetException
  4. {
  5. if (!override) {
  6. if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
  7. Class<?> caller = Reflection.getCallerClass();
  8. checkAccess(caller, clazz, null, modifiers);
  9. }
  10. }
  11. if ((clazz.getModifiers() & Modifier.ENUM) != 0)
  12. throw new IllegalArgumentException("Cannot reflectively create enum objects");
  13. ConstructorAccessor ca = constructorAccessor;
  14. // read volatile
  15. if (ca == null) {
  16. ca = acquireConstructorAccessor();
  17. }
  18. @SuppressWarnings("unchecked")
  19. T inst = (T) ca.newInstance(initargs);
  20. return inst;
  21. }
  22. private volatile ConstructorAccessor constructorAccessor;

用处

  • 实现自定义注解(AOP)
  • 实现动态代理(DI)
  • 可以访问一些私有变量和属性