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

网站页面数量梅州网站开发

网站页面数量,梅州网站开发,网站开发前端框架,建筑工程网点代表什么#x1f9d1; 博主简介#xff1a;CSDN博客专家#xff0c;历代文学网#xff08;PC端可以访问#xff1a;https://literature.sinhy.com/#/literature?__c1000#xff0c;移动端可微信小程序搜索“历代文学”#xff09;总架构师#xff0c;15年工作经验#xff0c;… 博主简介CSDN博客专家历代文学网PC端可以访问https://literature.sinhy.com/#/literature?__c1000移动端可微信小程序搜索“历代文学”总架构师15年工作经验精通Java编程高并发设计Springboot和微服务熟悉LinuxESXI虚拟化以及云原生Docker和K8s热衷于探索科技的边界并将理论知识转化为实际应用。保持对新技术的好奇心乐于分享所学希望通过我的实践经历和见解启发他人的创新思维。在这里我希望能与志同道合的朋友交流探讨共同进步一起在技术的世界里不断学习成长。 技术合作请加本人wx注明来自csdnforeast_sea 文章目录 Java 类加载机制详解类加载过程1Loading载入2Verification验证3Preparation准备4Resolution解析5Initialization初始化 类加载器双亲委派模型小结 Java 类加载机制详解 Java的类加载机制通过类加载器和类加载过程的合作确保了Java程序的动态加载、灵活性和安全性。双亲委派模型进一步增强了这种机制的安全性和类之间的协调性。 JVM 运行 Java 代码的时候JVM 需要将编译后的字节码文件加载到其内部的运行时数据区域中进行执行。这个过程涉及到了 Java 的类加载机制面试常问的知识点所以我们来详细地讲一讲。 字节码我们上一节也讲过它和类的加载机制息息相关相信大家都还有印象。 这里再给大家普及一个小技巧可以通过 xxd 命令来查看字节码文件先看下面这段代码。 public class Test {public static void main(String[] args) {System.out.println(沉默王二);} }代码编译通过后在命令行执行 xxd Test.classmacOS 用户可以直接执行Windows 用户可以戳这个链接获取替代品就可以快速查看字节码的十六进制内容。 xxd 是一个用于在终端中创建十六进制转储hex dump或将十六进制转回二进制的工具。可通过维基百科了解更多信息。 00000000: cafe babe 0000 0034 0022 0700 0201 0019 .......4....... 00000010: 636f 6d2f 636d 6f77 6572 2f6a 6176 615f com/cmower/java_ 00000020: 6465 6d6f 2f54 6573 7407 0004 0100 106a demo/Test......j 00000030: 6176 612f 6c61 6e67 2f4f 626a 6563 7401 ava/lang/Object. 00000040: 0006 3c69 6e69 743e 0100 0328 2956 0100 ..init...()V.. 00000050: 0443 6f64 650a 0003 0009 0c00 0500 0601 .Code........... 00000060: 000f 4c69 6e65 4e75 6d62 6572 5461 626c ..LineNumberTabl这里只说一点这段字节码中的 cafe babe 被称为“魔数”是 JVM 识别 .class 文件字节码文件的标志相信大家都知道Java 的 logo 是一杯冒着热气的咖啡是不是又关联上了 文件格式的定制者可以自由选择魔数值只要没用过比如说 .png 文件的魔数是 8950 4e47。 至于字节码文件中的其他内容暂时先不用去管我们后面会详细讲解。 类加载过程 知道什么是 Java 字节码后我们来聊聊 Java 的类加载过程。 类从被加载到 JVM 开始到卸载出内存整个生命周期分为七个阶段分别是加载、验证、准备、解析、初始化、使用和卸载。其中验证、准备和解析这三个阶段统称为连接。 除去使用和卸载就是 Java 的类加载过程。这 5 个阶段一般是顺序发生的但在动态绑定的情况下解析阶段发生在初始化阶段之后我们随后来解释。 1Loading载入 JVM 在该阶段的目的是将字节码从不同的数据源可能是 class 文件、也可能是 jar 包甚至网络转化为二进制字节流加载到内存中并生成一个代表该类的 java.lang.Class 对象在学反射的时候有讲过。 2Verification验证 JVM 会在该阶段对二进制字节流进行校验只有符合 JVM 字节码规范的才能被 JVM 正确执行。该阶段是保证 JVM 安全的重要屏障下面是一些主要的检查。 确保二进制字节流格式符合预期比如说是否以 cafe bene 开头前面提到过。是否所有方法都遵守访问控制关键字的限定protected、private 那些。方法调用的参数个数和类型是否正确。确保变量在使用之前被正确初始化了。检查变量是否被赋予恰当类型的值。还有更多。 3Preparation准备 JVM 会在该阶段对类变量也称为静态变量static 关键字修饰的分配内存并初始化对应数据类型的默认初始值如 0、0L、null、false 等。 也就是说假如有这样一段代码 public String chenmo 沉默; public static String wanger 王二; public static final String cmower 沉默王二;chenmo 不会被分配内存而 wanger 会但 wanger 的初始值不是“王二”而是 null。 需要注意的是static final 修饰的变量被称作为常量和类变量不同这些在讲 static 关键字就讲过了。常量一旦赋值就不会改变了所以 cmower 在准备阶段的值为“沉默王二”而不是 null。 4Resolution解析 该阶段将常量池中的符号引用转化为直接引用。 what符号引用直接引用 符号引用以一组符号任何形式的字面量只要在使用时能够无歧义的定位到目标即可来描述所引用的目标。 在编译时Java 类并不知道所引用的类的实际地址因此只能使用符号引用来代替。比如 com.Wanger 类引用了 com.Chenmo 类编译时 Wanger 类并不知道 Chenmo 类的实际内存地址因此只能使用符号 com.Chenmo。 直接引用通过对符号引用进行解析找到引用的实际内存地址。我们再来对比说明一下。 符号引用 定义包含了类、字段、方法、接口等多种符号的全限定名。特点在编译时生成存储在编译后的字节码文件的常量池中。独立性不依赖于具体的内存地址提供了更好的灵活性。 直接引用 定义直接指向目标的指针、相对偏移量或者能间接定位到目标的句柄。特点在运行时生成依赖于具体的内存布局。效率由于直接指向了内存地址或者偏移量所以通过直接引用访问对象的效率较高。 下面通过一张简化的图来描述它们的区别 在上面的例子中 class A 引用了 class B。在编译时这个引用变成了符号引用存储在 .class 文件的常量池中。在运行时当 class A 需要使用 class B 的时候JVM 会将符号引用解析为直接引用指向内存中的 class B 对象或其元数据。 通过这种方式Java 程序能够在编译时和运行时具有更高的灵活性和解耦性同时在运行时也能获得更好的性能。 Java 本身是一个静态语言但后面又加入了动态加载特性因此我们理解解析阶段需要从这两方面来考虑。 如果不涉及动态加载那么一个符号的解析结果是可以缓存的这样可以避免多次解析同一个符号因为第一次解析成功后面多次解析也必然成功第一次解析异常后面重新解析也会是同样的结果。 如果使用了动态加载前面使用动态加载解析过的符号后面重新解析结果可能会不同。使用动态加载时解析过程发生在在程序执行到这条指令的时候这就是为什么前面讲的动态加载时解析会在初始化后执行。 整个解析阶段主要做了下面几个工作 类或接口的解析类方法解析接口方法解析字段解析 5Initialization初始化 该阶段是类加载过程的最后一步。在准备阶段类变量已经被赋过默认初始值而在初始化阶段类变量将被赋值为代码期望赋的值。换句话说初始化阶段是执行类构造器方法javap 中看到的 clinit() 方法的过程。 上面这段话可能说得很抽象不好理解我来举个例子。 String cmower new String(沉默王二);上面这段代码使用了 new 关键字来实例化一个字符串对象那么这时候就会调用 String 类的构造方法对 cmower 进行实例化。 public String(String original) {this.value original.value;this.hash original.hash; }初始化时机包括以下这些 创建类的实例时。访问类的静态方法或静态字段时除了 final 常量它们在编译期就已经放入常量池。使用 java.lang.reflect 包的方法对类进行反射调用时。初始化一个类的子类首先会初始化父类。JVM 启动时用户指定的主类包含 main 方法的类将被初始化。 类加载器 聊完类加载过程就不得不聊聊类加载器。 一般来说Java 程序员并不需要直接同类加载器进行交互。JVM 默认的行为就已经足够满足大多数情况的需求了。不过如果遇到了需要和类加载器进行交互的情况而对类加载器的机制又不是很了解的话就不得不花大量的时间去调试 ClassNotFoundException 和 NoClassDefFoundError 等异常前面讲过。 对于任意一个类都需要由它的类加载器和这个类本身一同确定其在 JVM 中的唯一性。也就是说如果两个类的加载器不同即使两个类来源于同一个字节码文件那这两个类就必定不相等比如两个类的 Class 对象不 equals。 来通过一段简单的代码了解下。 /*** author 微信搜「沉默王二」回复关键字 PDF*/ public class Test {public static void main(String[] args) {ClassLoader loader Test.class.getClassLoader();while (loader ! null) {System.out.println(loader);loader loader.getParent();}} }每个 Java 类都维护着一个指向定义它的类加载器的引用通过 类名.class.getClassLoader() 可以获取到此引用然后通过 loader.getParent() 可以获取类加载器的上层类加载器。 上面这段代码的输出结果如下 jdk.internal.loader.ClassLoaders$AppClassLoader512ddf17 jdk.internal.loader.ClassLoaders$PlatformClassLoader2d209079第一行输出为 Test 的类加载器即应用类加载器它是 jdk.internal.loader.ClassLoaders$AppClassLoader 类的实例第二行输出为平台类加载器是 jdk.internal.loader.ClassLoaders$PlatformClassLoader 类的实例。那启动类加载器呢 按理说扩展类加载器的上层类加载器是启动类加载器但启动类加载器是虚拟机的内置类加载器通常表示为 null。 也就是说类加载器可以分为四种类型 ①、引导类加载器Bootstrap ClassLoader负责加载 JVM 基础核心类库如 rt.jar、sun.boot.class.path 路径下的类。 ②、扩展类加载器Extension ClassLoader负责加载 Java 扩展库中的类例如 jre/lib/ext 目录下的类或由系统属性 java.ext.dirs 指定位置的类。 ③、系统应用类加载器System ClassLoader负责加载系统类路径 java.class.path 上指定的类库通常是你的应用类和第三方库。 ④、用户自定义类加载器Java 允许用户创建自己的类加载器通过继承 java.lang.ClassLoader 类的方式实现。这在需要动态加载资源、实现模块化框架或者特殊的类加载策略时非常有用。 import java.io.*;public class CustomClassLoader extends ClassLoader {private String pathToBin;public CustomClassLoader(String pathToBin) {this.pathToBin pathToBin;}Overrideprotected Class? findClass(String name) throws ClassNotFoundException {try {byte[] classData loadClassData(name);return defineClass(name, classData, 0, classData.length);} catch (IOException e) {throw new ClassNotFoundException(Class name not found, e);}}private byte[] loadClassData(String name) throws IOException {String file pathToBin name.replace(., File.separatorChar) .class;InputStream is new FileInputStream(file);ByteArrayOutputStream byteSt new ByteArrayOutputStream();int len 0;while ((len is.read()) ! -1) {byteSt.write(len);}return byteSt.toByteArray();} }这个自定义类加载器做了以下几件事情 构造器接受一个字符串参数这个字符串指定了类文件的存放路径。覆写 findClass 方法当父类加载器无法加载类时findClass 方法会被调用。在这个方法中首先使用 loadClassData 方法读取类文件的字节码然后调用 defineClass 方法来将这些字节码转换为 Class 对象。loadClassData 方法读取指定路径下的类文件内容并将内容作为字节数组返回。 双亲委派模型 双亲委派模型Parent Delegation Model是 Java 类加载器使用的一种机制用于确保 Java 程序的稳定性和安全性。在这个模型中类加载器在尝试加载一个类时首先会委派给其父加载器去尝试加载这个类只有在父加载器无法加载该类时子加载器才会尝试自己去加载。 委派给父加载器当一个类加载器接收到类加载的请求时它首先不会尝试自己去加载这个类而是将这个请求委派给它的父加载器。 递归委派这个过程会递归向上进行从启动类加载器Bootstrap ClassLoader开始再到扩展类加载器Extension ClassLoader最后到系统类加载器System ClassLoader。 加载类如果父加载器可以加载这个类那么就使用父加载器的结果。如果父加载器无法加载这个类它没有找到这个类子加载器才会尝试自己去加载。 安全性和避免重复加载这种机制可以确保不会重复加载类并保护 Java 核心 API 的类不被恶意替换。 类加载器的层级结构如下图所示 Bootstrap ClassLoader↑│ Extension ClassLoader↑│ System/Application ClassLoader↑│ Custom ClassLoader这种层次关系被称作为双亲委派模型如果一个类加载器收到了加载类的请求它会先把请求委托给上层加载器去完成上层加载器又会委托上上层加载器一直到最顶层的类加载器如果上层加载器无法完成类的加载工作时当前类加载器才会尝试自己去加载这个类。 PS双亲委派模型突然让我联想到朱元璋同志这个同志当上了皇帝之后连宰相都不要了所有的事情都亲力亲为只有自己没精力没时间做的事才交给大臣们去干。 使用双亲委派模型有一个很明显的好处那就是 Java 类随着它的类加载器一起具备了一种带有优先级的层次关系这对于保证 Java 程序的稳定运作很重要。 上文中曾提到如果两个类的加载器不同即使两个类来源于同一个字节码文件那这两个类就必定不相等——双亲委派模型能够保证同一个类最终会被特定的类加载器加载。 小结 Java 的类加载机制通过类加载器和类加载过程的合作确保了 Java 程序的动态加载、灵活性和安全性。双亲委派模型进一步增强了这种机制的安全性和类之间的协调性。
http://www.hkea.cn/news/14458499/

相关文章:

  • 栾川有做网站的吗wordpress建站镜像
  • 设计网站公司多少钱wordpress如何开启page页面评论
  • 自己做网站排版wordpress主题 vieu
  • dede网站模板怎么改爱城市网官方下载
  • 个人网站备案需要多久郴州网站建设费用价格
  • 做网站能申报只是产权么四川省建设注册资格中心网站
  • 品牌平价网站建设如何承接设计网站建设
  • 北京家居网站建设装饰设计培训
  • dz后台网站地图黑龙江中国建设监理协会网站
  • 有了空间怎么做网站网址查询服务中心
  • 做电商在什么网站珠珠宝宝网网站站建建设设
  • 网站排名顾问网页转微信小程序
  • 网站适配手机怎么做室内设计效果图 客厅
  • 不会代码可以做网站吗专门做二手的网站
  • 怎么用记事本做钓鱼网站wordpress发布软件
  • 珠海专业网站建设公司哪家好宁波seo快速优化平台
  • 重庆茂尔建设集团有限公司网站seo标题关键词怎么写
  • 免费手机网站系统wordpress和织梦百度收录
  • wordpress title description惠州seo排名公司
  • 品牌网球两个相同的网站对做优化有帮助
  • 网站站长如何赚钱网站建设基础教程视频
  • 做网站编辑要会什么施工企业项目管理中心岗位职责
  • 支付建设网站的费用什么科目wordpress 分类p
  • 移动互联网站开发与维护关于做血糖仪的网站
  • 网站推荐几个免费的营销型网站建设工资
  • 方案 网站wordpress360收录插件
  • dw做的网站怎么全屏稿定设计app下载
  • jsp是网站开发语言吗苏州高新区建设局网站
  • 东莞模板网站好wordpress 哪个好用吗
  • 高大上的平面设计网站杭州西湖区抖音seo哪里找