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

变身小说网址wordpressseo建站收费地震

变身小说网址wordpress,seo建站收费地震,陕西省建设工程质量监督局网站,湘潭seo公司选择24火星Java类加载器 代码经过编译变成了字节码打包成 Jar 文件。让 JVM 去加载需要的字节码#xff0c;变成持久代/元数据区上的 Class 对象#xff0c;接着执行程序逻辑。 类声明周期和加载过程 步骤#xff1a;加载-链接#xff08;校验-准备-解析#xff09;-…Java类加载器 代码经过编译变成了字节码打包成 Jar 文件。让 JVM 去加载需要的字节码变成持久代/元数据区上的 Class 对象接着执行程序逻辑。 类声明周期和加载过程 步骤加载-链接校验-准备-解析-初始化-使用-卸载 加载根据明确知道的 class 完全限定名, 来获取二进制 classfile 格式的字节流找到文件系统中/jar 包中/或存在于任何地方的“class 文件”。 如果找不到二进制表示形式则会抛出 NoClassDefFound 错误。 校验确保 class 文件里的字节流信息符合当前虚拟机的要求不会危害虚拟机的安全。 在某个类的加载过程中JVM 必须加载其所有的超类和接口。如果类层次结构有问题例如该类是自己的超类或接口,死循环了则 JVM 将抛出 ClassCircularityError。 而如果实现的接口并不是一个 interface或者声明的超类是一个 interface也会抛出 IncompatibleClassChangeError。 准备会创建静态字段, 并将其初始化为标准默认值(比如null或者0 值)并分配方法表即在方法区中分配这些变量所使用的内存空间。 准备阶段并未执行任何 Java 代码。public static int i 1备阶段i的值会被初始化为 0后面在类初始化阶段才会执行赋值为 1public static final int i 1如果使用 final 作为静态常量对应常量 i在准备阶段就会被赋值 1 解析进入可选的解析符号引用阶段。 也就是解析常量池主要有以下四种类或接口的解析、字段解析、类方法解析、接口方法解析。 编写的代码中当一个变量引用某个对象的时候这个引用在 .class 文件中是以符号引用来存储的相当于做了一个索引记录。在解析阶段就需要将其解析并链接为直接引用相当于指向实际对象。如果有了直接引用那引用的目标必定在堆中存在。加载一个 class 时, 需要加载所有的 super 类和 super 接口。 初始化 必须在类的首次“主动使用”时才能执行类初始化。 初始化的过程包括执行 类构造器方法static 静态变量赋值语句static 静态代码块 如果是一个子类进行初始化会先对其父类进行初始化保证其父类在子类之前进行初始化。所以其实在 java 中初始化一个类那么必然先初始化过 java.lang.Object 类因为所有的 java 类都继承自 java.lang.Object。 类加载时机 触发类的初始化情况 当虚拟机启动时初始化用户指定的主类就是启动执行的 main 方法所在的类当遇到用以新建目标类实例的 new 指令时初始化 new 指令的目标类就是 new 一个类的时候要初始化当遇到调用静态方法的指令时初始化该静态方法所在的类当遇到访问静态字段的指令时初始化该静态字段所在的类子类的初始化会触发父类的初始化如果一个接口定义了 default 方法那么直接实现或者间接实现该接口的类的初始化会触发该接口的初始化使用反射 API 对某个类进行反射调用时初始化这个类其实跟前面一样反射调用要么是已经有实例了要么是静态方法都需要初始化当初次调用 MethodHandle 实例时初始化该 MethodHandle 指向的方法所在的类。 同时以下几种情况不会执行类初始化 通过子类引用父类的静态字段只会触发父类的初始化而不会触发子类的初始化。定义对象数组不会触发该类的初始化。常量在编译期间会存入调用类的常量池中本质上并没有直接引用定义常量的类不会触发定义常量所在的类。通过类名获取 Class 对象不会触发类的初始化Hello.class 不会让 Hello 类初始化。通过 Class.forName 加载指定类时如果指定参数 initialize 为 false 时也不会触发类初始化其实这个参数是告诉虚拟机是否要对类进行初始化。Class.forName(“jvm.Hello”)默认会加载 Hello 类。通过 ClassLoader 默认的 loadClass 方法也不会触发初始化动作加载了但是不初始化。 示例: 诸如 Class.forName(), classLoader.loadClass() 等 Java API, 反射API, 以及 JNI_FindClass 都可以启动类加载。 JVM 本身也会进行类加载。 比如在 JVM 启动时加载核心类java.lang.Object, java.lang.Thread 等等。 类加载机制 类加载过程可以描述为“通过一个类的全限定名 a.b.c.XXClass 来获取描述此类的 Class 对象”这个过程由“类加载器ClassLoader”来完成。这样的好处在于子类加载器可以复用父加载器加载的类。 系统自带的类加载器分为三种 启动类加载器BootstrapClassLoader由 JVM 内部实现的在 Java 的 API 里无法拿到。 用来加载 Java 的核心类是用原生 C 代码来实现的可以看做是 JVM 自带的在代码层面无法直接获取到启动类加载器的引用所以不允许直接操作它。例如java.lang.String 是由启动类加载器加载的所以 String.class.getClassLoader() 就会返回 null。但是后面可以看到可以通过命令行参数影响它加载什么。 扩展类加载器ExtClassLoader 负责加载 JRE 的扩展目录lib/ext 或者由 java.ext.dirs 系统属性指定的目录中的 JAR 包的类代码里直接获取它的父类加载器为 null因为无法拿到启动类加载器。类加载器在 Oracle Hotspot JVM 里都是在中sun.misc.Launcher定义的。一般都继承自URLClassLoader类这个类也默认实现了从各种不同来源加载 class 字节码转换成 Class 的方法。 应用类加载器AppClassLoader 负责在 JVM 启动时加载来自 Java 命令的 -classpath 或者 -cp 选项、java.class.path 系统属性指定的 jar 包和类路径。在应用程序代码里可以通过 ClassLoader 的静态方法 getSystemClassLoader() 来获取应用类加载器。如果没有特别指定则在没有使用自定义类加载器情况下用户自定义的类都由此加载器加载。类加载器在 Oracle Hotspot JVM 里都是在中sun.misc.Launcher定义的一般都继承自URLClassLoader类这个类也默认实现了从各种不同来源加载 class 字节码转换成 Class 的方法。 自定义类加载器。 自定义类加载器都以应用类加载器作为父加载器。应用类加载器的父类加载器为扩展类加载器。这些类加载器是有层次关系的启动加载器又叫根加载器是扩展加载器的父加载器但是直接从 ExClassLoader 里拿不到它的引用同样会返回 null。 类加载机制 双亲委托当一个自定义类加载器需要加载一个类比如 java.lang.String先委托自己的父加载器去加载父加载器如果发现自己还有父加载器会一直往前找这样只要上级加载器比如启动类加载器已经加载了某个类比如 java.lang.String所有的子加载器都不需要自己加载了。如果几个类加载器都没有加载到指定名称的类那么会抛出 ClassNotFountException 异常。负责依赖如果一个加载器在加载某个类的时候发现这个类依赖于另外几个类或接口也会去尝试加载这些依赖项。缓存加载为了提升加载效率消除重复加载一旦某个类被一个类加载器加载那么它会缓存这个加载结果不会重复加载。 自定义类加载器示例 public class Hello {static {System.out.println(Hello Class Initialized!);} }import java.util.Base64;public class HelloClassLoader extends ClassLoader {public static void main(String[] args) {try {new HelloClassLoader().findClass(jvm.Hello).newInstance(); // 加载并初始化Hello类} catch (ClassNotFoundException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();}}Overrideprotected Class? findClass(String name) throws ClassNotFoundException {String helloBase64 yv66vgAAADQAHwoABgARCQASABMIABQKABUAFgcAFwcAGAEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2N hbFZhcmlhYmxlVGFibGUBAAR0aGlzAQALTGp2bS9IZWxsbzsBAAg8Y2xpbml0PgEAClNvdXJjZUZpbGUBAApIZWxsby5qYXZhDAAHAAgHABkMABoAGwEAGEhlb GxvIENsYXNzIEluaXRpYWxpemVkIQcAHAwAHQAeAQAJanZtL0hlbGxvAQAQamF2YS9sYW5nL09iamVjdAEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2 YS9pby9QcmludFN0cmVhbTsBABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgAhAAUABgAAAAAAAgABAAcACA ABAAkAAAAvAAEAAQAAAAUqtwABsQAAAAIACgAAAAYAAQAAAAMACwAAAAwAAQAAAAUADAANAAAACAAOAAgAAQAJAAAAJQACAAAAAAAJsgACEgO2AASxAAAAAQAK AAAACgACAAAABgAIAAcAAQAPAAAAAgAQ;byte[] bytes decode(helloBase64);return defineClass(name,bytes,0,bytes.length);}public byte[] decode(String base64){return Base64.getDecoder().decode(base64);}}两个没有关系的自定义类加载器之间加载的类是不共享的只共享父类加载器兄弟之间不共享这样就可以实现不同的类型沙箱的隔离性可以用多个类加载器各自加载同一个类的不同版本在这个基础上可以实现类的动态加载卸载热插拔的插件机制等。 实用技巧 排查再找不到jar包的问题 结果可以看到三种类加载器各自默认加载了哪些 jar 包和包含了哪些 classpath 的路径 import java.lang.reflect.Field; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList;public class JvmClassLoaderPrintPath {public static void main(String[] args) {// 启动类加载器URL[] urls sun.misc.Launcher.getBootstrapClassPath().getURLs();System.out.println(启动类加载器);for(URL url : urls) {System.out.println( url.toExternalForm());}// 扩展类加载器printClassLoader(扩展类加载器, JvmClassLoaderPrintPath.class.getClassLoader().getParent());// 应用类加载器printClassLoader(应用类加载器, JvmClassLoaderPrintPath.class.getClassLoader());}public static void printClassLoader(String name, ClassLoader CL){if(CL ! null) {System.out.println(name ClassLoader - CL.toString());printURLForClassLoader(CL);}else{System.out.println(name ClassLoader - null);}}public static void printURLForClassLoader(ClassLoader CL){Object ucp insightField(CL,ucp);Object path insightField(ucp,path);ArrayList ps (ArrayList) path;for (Object p : ps){System.out.println( p.toString());}}private static Object insightField(Object obj, String fName) {try {Field f null;if(obj instanceof URLClassLoader){f URLClassLoader.class.getDeclaredField(fName);}else{f obj.getClass().getDeclaredField(fName);}f.setAccessible(true);return f.get(obj);} catch (Exception e) {e.printStackTrace();return null;}} } 如何排查类的方法不一致的问题 假如确定一个 jar 或者 class 已经在 classpath 里了但是却总是提示java.lang.NoSuchMethodError很可能是加载了错误的或者重复加载了不同版本的 jar 包。用前面的方法就可以先排查一下加载了具体什么 jar然后是不是不同路径下有重复的 class 文件但是版本不一样。 怎么看到加载了哪些类以及加载顺序 假如有两个地方有 Hello.class一个是新版本一个是旧的怎么才能直观地看到他们的加载顺序呢可以直接打印加载的类清单和加载顺序。只需要在类的启动命令行参数加上-XX:TraceClassLoading 或者 -verbose 即可注意需要加载 Java 命令之后要执行的类名之前不然不起作用。例如java -XX:TraceClassLoading jvm.HelloClassLoader 怎么调整或修改 ext 和本地加载路径 从前面的例子我们可以看到假如什么都不设置直接执行 java 命令默认也会加载非常多的 jar 包怎么可以自定义加载哪些 jar 包呢比如我的代码很简单只加载 rt.jar 行不行答案是肯定的。 $ java -Dsun.boot.class.pathD:\Program Files\Java\jre1.8.0_231\lib\rt.jar -Djava.ext.dirs jvm.JvmClassLoaderPrintPath启动类加载器 file:/D:/Program%20Files/Java/jdk1.8.0_231/jre/lib/rt.jar 扩展类加载器 ClassLoader - sun.misc.Launcher$ExtClassLoader15db9742 应用类加载器 ClassLoader - sun.misc.Launcher$AppClassLoader73d16e93 file:/D:/git/studyjava/build/classes/java/main/ file:/D:/git/studyjava/build/resources/main我们看到启动类加载器只加载了 rt.jar而扩展类加载器什么都没加载这就达到了我们的目的。命令行参数-Dsun.boot.class.path表示我们要指定启动类加载器加载什么最基础的东西都在 rt.jar 这个包了里所以一般配置它就够了。需要注意的是因为在 windows 系统默认 JDK 安装路径有个空格所以需要把整个路径用双引号括起来如果路径没有空格或是 Linux/Mac 系统就不需要双引号了。参数-Djava.ext.dirs表示扩展类加载器要加载什么一般情况下不需要的话可以直接配置为空即可。 怎么运行期加载额外的 jar 包或者 class 呢 有时候在程序已经运行了以后还想要再额外的去加载一些 jar 或类.简单说就是不使用命令行参数的情况下怎么用代码来运行时改变加载类的路径和方式 假如说在d:/app/jvm路径下有刚才使用过的 Hello.class 文件怎么在代码里能加载这个 Hello 类呢 一个是自定义 ClassLoader 的方式还有一个是直接在当前的应用类加载器里使用 URLClassLoader 类的方法 addURL不过这个方法是 protected 的需要反射处理一下然后又因为程序在启动时并没有显示加载 Hello 类所以在添加完了 classpath 以后没法直接显式初始化需要使用 Class.forName 的方式来拿到已经加载的Hello类Class.forName(“jvm.Hello”)默认会初始化并执行静态代码块。代码如下 package jvm;import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader;public class JvmAppClassLoaderAddURL {public static void main(String[] args) {String appPath file:/d:/app/;URLClassLoader urlClassLoader (URLClassLoader) JvmAppClassLoaderAddURL.class.getClassLoader();try {Method addURL URLClassLoader.class.getDeclaredMethod(addURL, URL.class);addURL.setAccessible(true);URL url new URL(appPath);addURL.invoke(urlClassLoader, url);Class.forName(jvm.Hello); // 效果跟Class.forName(jvm.Hello).newInstance()一样} catch (Exception e) {e.printStackTrace();}} }执行以下结果如下 $ java JvmAppClassLoaderAddURL Hello Class Initialized! 结果显示 Hello 类被加载成功的初始化并执行了其中的代码逻辑。
http://www.w-s-a.com/news/543474/

相关文章:

  • 技术支持 骏域网站建设专家佛山网站运营管理教材
  • 个体营业执照可以做网站服务吗电商运营学校培训
  • 企业网站免费推广的方法.wordpress 爱情模板下载地址
  • 轻淘客 轻网站怎么做手机开发人员选项怎么打开
  • 天津做网站制作公司html网站 下载
  • 哪个网站的课件做的好crm客户管理系统全称
  • 网站建设工作室创业计划书seo是什么职位的简称
  • o2o平台网站开发什么是白帽seo
  • 免费建个人手机网站WordPress 简历库
  • 建网站 是否 数据库阳瘘的最佳治疗方法是什么
  • 知晓程序网站怎么做网站基础维护
  • 兼职做网站赚钱吗图片设计制作哪个软件好手机
  • 做手机旅游网站智慧校园登录入口
  • 莆田网站建设维护国外极简网站
  • 百度怎样收录网站缪斯设计集团
  • 网站建设在开封找谁做wordpress 数据转换
  • 旅游网站开发的流程江苏付费网络推广培训
  • 网站软文标题2018wordpress主题
  • 德清网站设计wordpress免登录发布接
  • 可以做游戏的网站有哪些客户关系管理系统的主要功能
  • 整人关不掉的网站怎么做广东省网站免备案表
  • 网站设计素材edu域名网站
  • 中山学校的网站建设wordpress文章图片显示不出
  • 兰溪城市建设规划网站网站联盟的基本流程
  • 免费推广网站注册入口小说阅读网站怎么建设
  • 新网站怎么做网络推广怎么做企业网站排名
  • jsp商业网站开发网站链接如何做二维码
  • 江苏高校品牌专业建设网站怎么制作网站搜索窗口
  • 北京app建设 网站开发公司织梦网站seo
  • 大学网站 作风建设专题汽车配件外贸出口公司