随州制作网站,怎样做网站推销产品,客户网站开发全流程,jsp网站有哪些算上大学#xff0c;尽管接触Java已经有4年时间并对基本的API算得上熟练应用#xff0c;但是依旧觉得自己对于Java的特性依然是一知半解。要成为优秀的Java开发人员#xff0c;需要深入了解Java平台的工作方式#xff0c;其中类加载机制和JVM字节码这样的核心特性。今天我将…算上大学尽管接触Java已经有4年时间并对基本的API算得上熟练应用但是依旧觉得自己对于Java的特性依然是一知半解。要成为优秀的Java开发人员需要深入了解Java平台的工作方式其中类加载机制和JVM字节码这样的核心特性。今天我将记录一下我在新的学习路程中对Java类加载机制的理解。1.类加载机制类加载是一个将类合并到正在运行着的JVM进程中的过程。首先要加载一个类我们必须先得将类文件加载进来并连接并且要加上大量的验证随后会生成一个代表着这个类的class对象然后就可以通过它去创建新的实例了。这就是我所理解的Java的类加载机制。经过加载和连接后出来的class对象说明这个类已经被加载到了JVM中此后就不会再加载了。2.类加载器和双亲委派模型Java平台里有几个经典的类加载器它们分别在平台的启动和常规操作中承担不同的任务 根类加载器Bootstrap ClassLoader——通常在虚拟机启动不久后实例化我们可以将其视作JVM的一部分他的作用通常是负责加载系统的基础jar包主要是rt.jar,并且它不做验证工作。我们开发者无法直接使用该加载器 扩展类加载器Extension ClassLoader——用来加载安装时自带的标准扩展。一般包括安全性扩展。我们开发者可以直接使用。 应用或系统类加载器System ClassLoader——这是应用最广泛的类加载器。它负责加载应用类。 定制类加载器Custom ClassLoader——在更复杂的环境中我们开发者可以通过继承java.lang.ClassLoader类的方式实现自己的类加载器以满足一些特殊的需求。比如说Spring框架里的封装了自己的类加载器我会在随后的spring源码学习中遇到的吧 线程上下文类加载器Context ClassLoader——默认为系统类加载器可通过Thread.currentThread().setContextClassLoader(ClassLoader)来设置每个线程都可以将线程上下文类加载器预先设置为父线程的类加载器。这个主要用于打破双亲委派模型容许父类加载器通过子类加载器加载所需要的类库。说到双亲委派模型我们可以通过这个图可知如果说一个类加载器收到类加载请求它并不会马上去找它会先把这个请求委托给他的父类加载器去完成只有它的父类加载器反馈说找不到了它才会自己去找注父类加载器它们的默认的目录路径都是不一样的一个类在虚拟机里面是用它的全限定类名它的类加载器来确立它的唯一性采用双亲委派的好处可以保证系统中的类不混乱如你自己写了一个java.lang.object类并且路径也放在lib下面此时编译后会有两个object类了采用双亲委派就只会加载rt.jar里面的object而不加载你自己写的。3.加载类手动加载类有两种方式Class.forName()和ClassLoader.loadClass()两种我们从源码来看看他们的区别Class.forName()它有两个重载方法 pre namecode classjava public static Class? forName(String className) throws ClassNotFoundException { return forName0(className, true, ClassLoader.getCallerClassLoader()); } public static Class? forName(String name, boolean initialize, ClassLoader loader) throws ClassNotFoundException { if (loader null) { SecurityManager sm System.getSecurityManager(); if (sm ! null) { ClassLoader ccl ClassLoader.getCallerClassLoader(); if (ccl ! null) { sm.checkPermission( SecurityConstants.GET_CLASSLOADER_PERMISSION); } } } return forName0(name, initialize, loader); } /** Called after security checks have been made. */ private static native Class? forName0(String name, boolean initialize, ClassLoader loader) throws ClassNotFoundException;第一个方法默认初始化类。第二个方法可以选择是否初始化类和可以选择类加载器。它们俩最终都是返回forName0而forName0有native关键字原生态的方法是其他语言实现的我就不深究下去了。ClassLoader.loadClass()它同样也有两个重载方法 public Class? loadClass(String name) throws ClassNotFoundException { return loadClass(name, false); } protected Class? loadClass(String name, boolean resolve) throws ClassNotFoundException { synchronized (getClassLoadingLock(name)) { // First, check if the class has already been loaded 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 stats sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); sun.misc.PerfCounter.getFindClasses().increment(); } } if (resolve) { resolveClass(c); } return c; } }第一个方法的具体实现是第二个方法。resolve参数为false。第二个方法先检查这个类是否被加载过如果没有被加载过那就通过双亲委派的模式去找如果父类加载器不是根类加载器那就递归调用如果是那就试着返回根类加载器所加载的类或者返回null当虚拟机想要装入的不仅包括指定的类似resolve参数为true装入该类英语的所有其他类。这个方法还用了其他的类它们基本都是用native修饰的在这也不深究知道是用来干嘛的就好了。以上就是我所学习的关于Java类加载器的内容。https://blog.csdn.net/donggua3694857/article/details/51932630 转载于:https://www.cnblogs.com/ldq2016/p/10308653.html