当前位置: 首页 > news >正文

织梦网站地图生成建设银行租房网站首页

织梦网站地图生成,建设银行租房网站首页,在源码之家下载的网站模板可以作为自己的网站吗,wordpress可以商用吗写在前面#xff1a;Java中的所有类#xff0c;必须被装载到jvm中才能运行#xff0c;这个装载工作是由jvm中的类装载器完成的#xff0c;类装载器所做的工作实质是把类文件从硬盘读取到内存中#xff0c;JVM在加载类的时候#xff0c;都是通过ClassLoader的loadClassJava中的所有类必须被装载到jvm中才能运行这个装载工作是由jvm中的类装载器完成的类装载器所做的工作实质是把类文件从硬盘读取到内存中JVM在加载类的时候都是通过ClassLoader的loadClass方法来加载class的loadClass使用双亲委派模式。 为了更好的理解类的加载机制我们来深入研究一下ClassLoader和他的loadClass方法。 源码分析 1 public abstract class ClassLoader ClassLoader类是一个抽象类sun公司是这么解释这个类的 1 2 3 4 5 6 7 /**  * A class loader is an object that is responsible for loading classes. The  * class ClassLoader is an abstract class.  Given the binary name of a class, a class loader should attempt to  * locate or generate data that constitutes a definition for the class.  A  * typical strategy is to transform the name into a file name and then read a  * class file of that name from a file system. **/ 大致意思如下 class loader是一个负责加载classes的对象ClassLoader类是一个抽象类需要给出类的二进制名称class loader尝试定位或者产生一个class的数据一个典型的策略是把二进制名字转换成文件名然后到文件系统中找到该文件。 接下来我们看loadClass方法的实现方式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 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;         }     } 还是来看sun公司对该方法的解释 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 /**      * Loads the class with the specified binary name.  The      * default implementation of this method searches for classes in the      * following order:      *      *      *      *    Invoke {a hrefhttp://www.jobbole.com/members/57845349link/a #findLoadedClass(String)} to check if the class      *   has already been loaded.       *      *    Invoke the {a hrefhttp://www.jobbole.com/members/57845349link/a #loadClass(String) loadClass} method      *   on the parent class loader.  If the parent is null the class      *   loader built-in to the virtual machine is used, instead.       *      *    Invoke the {a hrefhttp://www.jobbole.com/members/57845349link/a #findClass(String)} method to find the      *   class.       *      *      *      *  If the class was found using the above steps, and the      * resolve flag is true, this method will then invoke the {a hrefhttp://www.jobbole.com/members/57845349link/a      * #resolveClass(Class)} method on the resulting Class object.      *      *  Subclasses of ClassLoader are encouraged to override {a hrefhttp://www.jobbole.com/members/57845349link/a      * #findClass(String)}, rather than this method.       *      *  Unless overridden, this method synchronizes on the result of      * {a hrefhttp://www.jobbole.com/members/57845349link/a #getClassLoadingLock getClassLoadingLock} method      * during the entire class loading process.      *      */ 大致内容如下: 使用指定的二进制名称来加载类这个方法的默认实现按照以下顺序查找类 调用findLoadedClass(String)方法检查这个类是否被加载过 使用父加载器调用loadClass(String)方法如果父加载器为Null类加载器装载虚拟机内置的加载器调用findClass(String)方法装载类 如果按照以上的步骤成功的找到对应的类并且该方法接收的resolve参数的值为true,那么就调用resolveClass(Class)方法来处理类。 ClassLoader的子类最好覆盖findClass(String)而不是这个方法。 除非被重写这个方法默认在整个装载过程中都是同步的线程安全的 接下来我们开始分析该方法。 **protected Class loadClass(String name, boolean resolve)** 该方法的访问控制符是protected也就是说该方法**同包内和派生类中可用** 返回值类型Class 这里用到**泛型**。这里使用通配符?作为泛型实参表示对象可以 接受任何类型(类类型)。因为该方法不知道要加载的类到底是什么类所以就用了通用的泛型。String name要查找的类的名字boolean resolve一个标志true表示将调用resolveClass(c)处理该类 throws ClassNotFoundException 该方法会抛出找不到该类的异常这是一个非运行时异常 synchronized (getClassLoadingLock(name)) 看到这行代码我们能知道的是这是一个同步代码块那么synchronized的括号中放的应该是一个对象。我们来看getClassLoadingLock(name)方法的作用是什么 1 2 3 4 5 6 7 8 9 10 11 protected Object getClassLoadingLock(String className) {         Object lock this;         if (parallelLockMap ! null) {             Object newLock new Object();             lock parallelLockMap.putIfAbsent(className, newLock);             if (lock null) {                 lock newLock;             }         }         return lock;     } 以上是getClassLoadingLock(name)方法的实现细节我们看到这里用到变量parallelLockMap 根据这个变量的值进行不同的操作如果这个变量是Null那么直接返回this如果这个属性不为Null那么就新建一个对象然后在调用一个putIfAbsent(className, newLock);方法来给刚刚创建好的对象赋值这个方法的作用我们一会讲。那么这个parallelLockMap变量又是哪来的那我们发现这个变量是ClassLoader类的成员变量 1 private final ConcurrentHashMap parallelLockMap; 这个变量的初始化工作在ClassLoader的构造函数中 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 private ClassLoader(Void unused, ClassLoader parent) {         this.parent parent;         if (ParallelLoaders.isRegistered(this.getClass())) {             parallelLockMap new ConcurrentHashMap();             package2certs new ConcurrentHashMap();             domains                 Collections.synchronizedSet(new HashSet());             assertionLock new Object();         } else {             // no finer-grained lock; lock on the classloader instance             parallelLockMap null;             package2certs new Hashtable();             domains new HashSet();             assertionLock this;         }     } 这里我们可以看到构造函数根据一个属性ParallelLoaders的Registered状态的不同来给parallelLockMap 赋值。 我去隐藏的好深好我们继续挖看看这个ParallelLoaders又是在哪赋值的呢我们发现在ClassLoader类中包含一个静态内部类private static class ParallelLoaders在ClassLoader被加载的时候这个静态内部类就被初始化。这个静态内部类的代码我就不贴了直接告诉大家什么意思sun公司是这么说的Encapsulates the set of parallel capable loader types意识就是说封装了并行的可装载的类型的集合。 上面这个说的是不是有点乱那让我们来整理一下 首先在ClassLoader类中有一个静态内部类ParallelLoaders他会指定的类的并行能力如果当前的加载器被定位为具有并行能力那么他就给parallelLockMap定义就是new一个 ConcurrentHashMap()那么这个时候我们知道如果当前的加载器是具有并行能力的那么parallelLockMap就不是Null这个时候我们判断parallelLockMap是不是Null如果他是null说明该加载器没有注册并行能力那么我们没有必要给他一个加锁的对象getClassLoadingLock方法直接返回this,就是当前的加载器的一个实例。如果这个parallelLockMap不是null那就说明该加载器是有并行能力的那么就可能有并行情况那就需要返回一个锁对象。然后就是创建一个新的Object对象调用parallelLockMap的putIfAbsent(className, newLock)方法这个方法的作用是首先根据传进来的className,检查该名字是否已经关联了一个value值如果已经关联过value值那么直接把他关联的值返回如果没有关联过值的话那就把我们传进来的Object对象作为value值className作为Key值组成一个map返回。然后无论putIfAbsent方法的返回值是什么都把它赋值给我们刚刚生成的那个Object对象。 这个时候我们来简单说明一下getClassLoadingLock(String className)的作用就是 为类的加载操作返回一个锁对象。为了向后兼容这个方法这样实现:如果当前的classloader对象注册了并行能力方法返回一个与指定的名字className相关联的特定对象否则直接返回当前的ClassLoader对象。 Class c findLoadedClass(name); 在这里在加载类之前先调用findLoadedClass方法检查该类是否已经被加载过findLoadedClass会返回一个Class类型的对象如果该类已经被加载过那么就可以直接返回该对象在返回之前会根据resolve的值来决定是否处理该对象具体的怎么处理后面会讲。 如果该类没有被加载过那么执行以下的加载过程 1 2 3 4 5 6 7 8 9 10 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 } 如果父加载器不为空那么调用父加载器的loadClass方法加载类如果父加载器为空那么调用虚拟机的加载器来加载类。 如果以上两个步骤都没有成功的加载到类那么 1 c findClass(name); 调用自己的findClass(name)方法来加载类。 这个时候我们已经得到了加载之后的类那么就根据resolve的值决定是否调用resolveClass方法。resolveClass方法的作用是 链接指定的类。这个方法给Classloader用来链接一个类如果这个类已经被链接过了那么这个方法只做一个简单的返回。否则这个类将被按照 Java™规范中的Execution描述进行链接…… 至此ClassLoader类以及loadClass方法的源码我们已经分析完了那么。结合源码的分析我们来总结一下 总结 java中的类大致分为三种 1.系统类 2.扩展类 3.由程序员自定义的类 类装载方式有两种: 1.隐式装载 程序在运行过程中当碰到通过new 等方式生成对象时隐式调用类装载器加载对应的类到jvm中。 2.显式装载 通过class.forname()等方法显式加载需要的类 类加载的动态性体现: 一个应用程序总是由n多个类组成Java程序启动时并不是一次把所有的类全部加载后再运行它总是先把保证程序运行的基础类一次性加载到jvm中其它类等到jvm用到的时候再加载这样的好处是节省了内存的开销因为java最早就是为嵌入式系统而设计的内存宝贵这是一种可以理解的机制而用到时再加载这也是java动态性的一种体现 java类装载器 1 2 3 4 5 6 7 8 9 10 11 Java中的类装载器实质上也是类功能是把类载入jvm中值得注意的是jvm的类装载器并不是一个而是三个层次结构如下   Bootstrap Loader  - 负责加载系统类         |       - - ExtClassLoader  - 负责加载扩展类                 |                - - AppClassLoader  - 负责加载应用类 为什么要有三个类加载器一方面是分工各自负责各自的区块另一方面为了实现委托模型下面会谈到该模型 类加载器之间是如何协调工作的 前面说了java中有三个类加载器问题就来了碰到一个类需要加载时它们之间是如何协调工作的即java是如何区分一个类该由哪个类加载器来完成呢。 在这里java采用了委托模型机制这个机制简单来讲就是“类装载器有载入类的需求时会先请示其Parent使用其搜索路径帮忙载入如果Parent 找不到,那么才由自己依照自己的搜索路径搜索类” 下面举一个例子来说明为了更好的理解先弄清楚几行代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Public class Test{     Public static void main(String[] arg){       ClassLoader c  Test.class.getClassLoader();  //获取Test类的类加载器         System.out.println(c);       ClassLoader c1 c.getParent();  //获取c这个类加载器的父类加载器         System.out.println(c1);       ClassLoader c2 c1.getParent();//获取c1这个类加载器的父类加载器         System.out.println(c2);   } } 运行结果 1 2 3 4 5 ……AppClassLoader…… ……ExtClassLoader…… Null 可以看出Test是由AppClassLoader加载器加载的AppClassLoader的Parent 加载器是 ExtClassLoader,但是ExtClassLoader的Parent为 null 是怎么回事呵朋友们留意的话前面有提到Bootstrap Loader是用C语言写的依java的观点来看逻辑上并不存在Bootstrap Loader的类实体所以在java程序代码里试图打印出其内容时我们就会看到输出为null。 类装载器ClassLoader一个抽象类描述一下JVM加载class文件的原理机制 类装载器就是寻找类或接口字节码文件进行解析并构造JVM内部对象表示的组件在java中类装载器把一个类装入JVM经过以下步骤 1、装载查找和导入Class文件 2、链接其中解析步骤是可以选择的 a检查检查载入的class文件数据的正确性 b准备给类的静态变量分配存储空间 c解析将符号引用转成直接引用 3、初始化对静态变量静态代码块执行初始化工作 类装载工作由ClassLoder和其子类负责。JVM在运行时会产生三个ClassLoader根装载器ExtClassLoader(扩展类装载器)和AppClassLoader其中根装载器不是ClassLoader的子类由C编写因此在java中看不到他负责装载JRE的核心类库如JRE目录下的rt.jar,charsets.jar等。ExtClassLoader是ClassLoder的子类负责装载JRE扩展目录ext下的jar类包AppClassLoader负责装载classpath路径下的类包这三个类装载器存在父子层级关系****即根装载器是ExtClassLoader的父装载器ExtClassLoader是AppClassLoader的父装载器。默认情况下使用AppClassLoader装载应用程序的类 Java装载类使用“全盘负责委托机制”。“全盘负责”是指当一个ClassLoder装载一个类时除非显示的使用另外一个ClassLoder该类所依赖及引用的类也由这个ClassLoder载入“委托机制”是指先委托父类装载器寻找目标类只有在找不到的情况下才从自己的类路径中查找并装载目标类。这一点是从安全方面考虑的试想如果一个人写了一个恶意的基础类如java.lang.String并加载到JVM将会引起严重的后果但有了全盘负责制java.lang.String永远是由根装载器来装载避免以上情况发生 除了JVM默认的三个ClassLoder以外第三方可以编写自己的类装载器以实现一些特殊的需求。类文件被装载解析后在JVM中都有一个对应的java.lang.Class对象提供了类结构信息的描述。数组枚举及基本数据类型甚至void都拥有对应的Class对象。Class类没有public的构造方法Class对象是在装载类时由JVM通过调用类装载器中的defineClass()方法自动构造的。 http://blog.jobbole.com/96145/?utm_sourcehao.jobbole.comutm_mediumrelatedArticle
http://www.huolong8.cn/news/107400/

相关文章:

  • 上海网站建设价钱wordpress 居中
  • 网站开发经费申请报告长沙房地产价格
  • 网站建设营销推广企业建网站需要准备哪些资料呢
  • 考研培训机构排名前五的机构深圳优化怎么做搜索
  • p2p 金融网站开发郑州百度seo网站优化
  • 网站设计规划信息技术教案项目分享网
  • 电子商务网站创建过程淄博网站优化公司
  • 网站服务器使用怎么建设网站后台
  • 蔡甸网站建设礼品兑换网站怎么做
  • 建国外网站买完域名后怎么做常德百度推广运营
  • 网站用户界面设计重庆邮电大学官网网站
  • 淘宝客建站模板有什么教做维c甜品的网站
  • 不懂代码如何做网站如何建设旅游网站
  • 网站快速排名技术关于网站建设的小故事
  • 网站改版方案原则晋城北京网站建设
  • 说做网站被收债管理咨询公司税收优惠
  • 建一个网站的手机电脑平阳网站建设公司
  • 海南哪家公司做网站做的好网络营销方法案例
  • 做网站找个人企业网络营销策划书
  • 合肥网站优化价格濮阳建设网
  • 启用中文域名大网站百度云资源搜索引擎
  • 域名过期做的网站怎么办百度点击率排名有效果吗
  • php网站的数据库在哪wordpress手动备份
  • 制作网站要找什么公司集团网站设计思路
  • 企业建站 源码wordpress有微信主题吗
  • 学校官网网站建设的现状分析成都网站建设开发
  • 做货代用的网站设计主题网站
  • 诚信档案建设网站有哪些网站做二手房好的
  • 高明网站开发源码制作网站
  • jsp建网站简单项目计划书