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

如何做商城网站防下载 的视频网站 怎么做

如何做商城网站,防下载 的视频网站 怎么做,自已建网站微信登录,效果好的魔站建站系统JDK版本#xff1a;jdk8 IDEA版本#xff1a;IntelliJ IDEA 2022.1.3 文章目录 一. 生命周期概述二. 加载阶段(Loading)2.1 加载步骤2.2 查看内存中的对象 三. 连接阶段(Linking)3.1 连接之验证3.2 连接之准备3.3 连接阶段之解析 四. 初始化阶段(Initialization)4.1 单个类的… JDK版本jdk8 IDEA版本IntelliJ IDEA 2022.1.3 文章目录 一. 生命周期概述二. 加载阶段(Loading)2.1 加载步骤2.2 查看内存中的对象 三. 连接阶段(Linking)3.1 连接之验证3.2 连接之准备3.3 连接阶段之解析 四. 初始化阶段(Initialization)4.1 单个类的初始化4.2 子类继承父类的初始化 参考资料 一. 生命周期概述 概述 类的生命周期描述了一个类加载、使用、卸载的整个过程 二. 加载阶段(Loading) 2.1 加载步骤 1、类加载器根据类的全限定名通过不同的渠道以二进制流的方式获取字节码信息 有如下渠道 本地文件磁盘上的字节码文件动态代理生成程序运行时使用动态代理生成通过网络传输的类早期的Applet技术使用 2、类加载器在加载完类之后Jva虚拟机会将字节码中的信息保存到方法区中 3、类加载器在加载完类之后Jva虚拟机会将字节码中的信息保存到内存的方法区[虚概念]中生成一个InstanceKlass对象保存类的所有信息里边还包含实现特定功能比如多态的信息 4、同时Java虚拟机还会在堆中生成一份与方法区中数据类似的java.lang.Class对象它的作用是在Java代码中去获取类的信息以及存储静态字段的数据JDK8及之后 ❗️注意堆区中保存静态字段的数据 ❗️注意 方法区中的InstanceKlass对象与堆中的java.lang.Class对象相互关联你既可以通过InstanceKlass对象找到对应的java.lang.Class对象也可以通过java.lang.Class对象找到关联的InstanceKlass对象 示例代码如下 ClassPerson aClass Person.class; //获取定义的方法信息 Method[] methods aClass.getMethods(); //获取定义的字段信息 Field[] fields aClass.getFields();✔️分析如下 上述Java代码通过Person.class【反射】获取了Person类的Class对象【Java.lang.Class】然后通过该对象分别获取了该类中定义的方法信息和字段信息。 aClass.getMethods()返回Person类中所有公共方法包括继承自父类的方法的数组包括公共、保护、默认和私有方法但不包括构造方法。aClass.getFields()返回Person类中所有公共字段包括继承自父类的字段的数组包括公共、保护、默认和私有字段。 疑问 ①为什么JVM需要在方法区和堆区中各创建一个对象如果不要堆里的对象而只留方法区中的对象使用反射时只去获取方法区中的对象这样不是能节省一定的内存空间吗 原因 方法区中的InstanceKlass对象是使用C语言编写的对象而Java语言一般不能操纵使用C语言编写的对象所以JVM 会在堆区中创建一个使用Java编写的Java.lang.Object对象这样可以在Java代码中获取这个对象堆中的Java.lang.Object对象中的字段信息要少于方法区中的InstanceKlass对象而InstanceKlass对象中的所有信息对开发者来说并不是所有都需要的比如InstanceKlass对象中的虚方法表这个虚方法表是JVM在底层实现多态时而去使用对开发者而言完全不需要去使用它因此基于控制开发者访问部分数据的范围实现提升数据的安全性 所以对于开发者来说只需要访问堆中的Class对象而不需要访问方法区中所有信息。这样Java虚拟机就能很好地控制开发者访问数据的范围 你怎么知道静态字段的数据是保存在堆区或者说你怎么查看内存中的对象信息且看如下阐述 2.2 查看内存中的对象 案例 查看测试代码的内村信息这里以jdk8为例 import java.io.IOException;public class PersonDemo {public static final int i 1;public static void main(String[] args) throws IOException {PersonDemo personDemo new PersonDemo();System.in.read();} } 推荐使用 JDK自带的hsdb工具查看Java虚拟机内存信息工具位于JDK安装目录下lib文件夹中的sa-jdi.jar中。 步骤 ①打开jdk8所在的安装目录下lib文件夹下输入cmd回车打开命令窗口 ②输入命令java -cp sa-jdi.jar sun.jvm.hotspot.HSDB ③再打开一个cmd命令窗口运行命令jps以获取当前要查看的Java程序的进程ID ④ File - Attach to HotSpot process - 输入你要查看的Java程序的进程ID - OK ⑤输入要查看的Java进程ID点击OK我们就可以看到相应的进程信息 ⑥ Tools - Object Histogram 然后输入类的全类名找到指定的对象信息 ⑦按如下步骤查看对象的内存信息 总结 类在加载阶段中分别在方法区和堆区各创建了一个对象且静态变量存放在堆区中 三. 连接阶段(Linking) 3.1 连接之验证 它是连接Linking阶段的第一个环节主要目的是检测Java字节码文件是否遵守了《Java虚拟机规范》中的约束。这个阶段一般不需要程序员参与。 主要包含如下四部分具体详见《Java虚拟机规范》 1.文件格式验证比如文件是否以0xCAFEBABE开头主次版本号是否满足当前Java虚拟机版本要求。 案例 修改文件头的CA改为AA重新编译Java代码运行测试 运行如下 2.元信息验证例如类必须有父类(superz不能为空) 3.验证程序执行指令的语义比如方法内的指令执行中跳转到不正确的位置 4.符号引用验证例如是否访问了其他类中privatel的方法等 3.2 连接之准备 目的 为静态变量(static)分配内存并设置初始值jdk8 及之后的版本 注意 准备阶段只会给静态变量赋初始值而每一种基本数据类型和引用数据类型都有其初始值。 final修饰的基本数据类型的静态变量准备阶段直接会将代码中的值进行赋值 3.3 连接阶段之解析 目的 主要是将常量池中的符号引用替换为直接引用 而直接引用不再使用编号而是使用内存中地址进行访问具体的数据使用效率会更高 四. 初始化阶段(Initialization) 目的 初始化阶段会执行静态代码块中的代码并为静态变量赋值。执行流程与代码流程一致 ✔️Trips 初始化阶段会执行字节码文件中clinit部分[类的初始化]的字节码指令 4.1 单个类的初始化 案例 分析下面的代码中静态变量赋值过程 示例代码① public class PersonDemo {public static int i 1;static {i 2;}public static void main(String[] args) throws IOException {} } 字节码指令如下 解读如下 0: iconst_1 // 将整数值1压入操作数栈顶 1: putstatic #7 // 将操作数栈顶的值1存入常量池索引为7的静态字段4: iconst_2 // 将整数值2压入操作数栈顶 5: putstatic #7 // 将操作数栈顶的值2存入常量池索引为7的静态字段8: return // 结束当前方法此处为静态初始化块结合常量池信息由#7 com/fc/pojo/PersonDemo.i : I给出可以得知 常量池索引为7的项指向com.fc.pojo.PersonDemo类中的静态字段i类型为intI表示整型 代码示例② public class PersonDemo {static {i 2;}public static int i 1;public static void main(String[] args) throws IOException {} } 字节码指令如下 解读如下 0: iconst_2 // 将整数值2压入操作数栈顶 1: putstatic #7 // 将操作数栈顶的值2存入常量池索引为7的静态字段4: iconst_1 // 将整数值2压入操作数栈顶 5: putstatic #7 // 将操作数栈顶的值1存入常量池索引为7的静态字段8: return // 结束当前方法此处为静态初始化块clinit方法中的执行顺序与]ava中编写的顺序是一致的 ⭐️以下几种方式会导致类的初始化 1.访问一个类的静态变量或者静态方法注意变量是finl修饰的并且等号右边是常量不会触发初始化。 2.调用Class.forName(String className) 3.new一个该类的对象时 4.执行Main方法的当前类。 ✔️Trips 添加-XX:TraceClassLoading 参数可以打印出加载并初始化的类 使用步骤 ①按照如下步骤添加参数 ② 再次运行程序就会打印类的加载信息 ⚠️ 笔试例题 下例代码的输出结果是什么 代码示例如下 public class test1 {public static void main(String[] args) {System.out.println(A);}public test1(){System.out.println(B);}{System.out.println(C);}static {System.out.println(D);}} clinit指令在特定情况下不会出现比如如下几种情况是不会进行初始化指令执行的 无静态代码块且无静态变量赋值语句 有静态变量的声明但是没有赋值语句 public static int i;静态变量的定义使用final关键字这类变量会在准备阶段直接进行初始化 public static final int i 1;4.2 子类继承父类的初始化 直接访问父类的静态变量不会触发子类的初始化子类的初始化cliniti调用之前会先调用父类的clinit初始化方法 ⚠️ 笔试例题 下面代码的输出结果是什么 public class test03 {public static void main(String[] args){new B02();System.out.println(B02.a);}}class A02{static int a 0;static {a 1;} }class B02 extends A02{static {a 2;} }思考 ①以下代码的运行结果是什么 public class test3 {public static void main(String[] args){test03_A[] a new test03_A[5];} }class test03_A {static {System.out.println(test03_A的静态代码块执行);} }运行如下 ✔️分析如下 数组的创建本身确实不会导致数组中元素的类进行初始化。这里的“类初始化”指的是Java类加载机制中的类初始化阶段Class Initialization在这个阶段会执行类的静态初始化块static initialization blocks以及初始化所有的静态字段。数组的创建过程与类初始化是两个不同的概念其区别在于 数组创建 创建数组时JVM会为数组分配一块连续的内存空间来存放数组元素。对于基本类型数组如int[]、double[]等数组元素会被自动赋予该类型的默认值如int数组元素默认为0。对于引用类型数组如String[]、MyClass[]等数组元素则被初始化为null。这个过程仅仅是为数组分配内存和设置初始值并不涉及数组元素所指向的具体类的初始化。 类初始化 类初始化发生在类的首次主动使用时包括 调用类的静态方法访问类的静态字段除final常量外因为final常量在编译期间就已经确定无需运行时初始化实例化类的实例使用反射调用类的方法或访问字段初始化子类时如果父类还未初始化则先初始化父类当满足上述条件之一时JVM会确保类的初始化阶段被执行包括执行静态初始化块和初始化静态字段。 回到数组创建的话题数组只是存储元素的容器创建数组时并未触发对数组元素的任何方法调用或字段访问更没有实例化数组元素对应的类。因此数组创建并不会直接导致数组元素所代表的类进行初始化。只有当后续代码中显式地访问或实例化这些数组元素时才会触发相应的类初始化。 举个例子 MyClass[] myArray new MyClass[10];在这段代码中创建了一个长度为10的MyClass对象数组。数组创建完毕后数组中的所有元素都被初始化为null。此时MyClass类并没有被初始化因为没有发生上述类初始化的触发条件。只有当后续代码试图实例化其中一个数组元素如 myArray[0] new MyClass();这时才真正触发了MyClass的实例化即类初始化因为创建MyClass实例属于类的主动使用。 总结来说数组的创建仅涉及内存分配和元素的默认初始化基本类型为默认值引用类型为null并不引发数组元素所代表的类的初始化。类初始化是在后续代码中当首次主动使用该类时由JVM自动触发的。 结论 数组的创建不会导致数组中元素的类进行初始化 ②类的初始化和对象的实例化是同一个概念吗 类的初始化和对象的实例化是Java编程中两个相关但不同的概念。它们分别对应着Java类生命周期的不同阶段。简单来说 类的初始化 发生时间类的初始化发生在类第一次被加载到JVMJava虚拟机并且准备使用时。具体来说当某个类首次被主动使用如创建该类的实例、访问该类的静态成员、调用该类的静态方法等或者其子类被加载时JVM会确保该类已经被加载并完成初始化。目的为类的静态成员设置初始状态执行必要的静态资源准备工作。主要内容 静态成员变量的初始化按照声明顺序为类的静态成员变量赋初值。静态初始化块Static Initialization Block的执行如果类中定义了静态初始化块这些代码将在类加载期间按其出现顺序依次执行。父类的初始化若当前类有父类且尚未被初始化会先递归初始化其直接父类及其祖先类。 对象的实例化 发生时间对象的实例化发生在运行时当使用 new 关键字、反射API或者其他能够创建新对象的方式显式地创建类的一个实例时。目的创建出一个具体的类实例为实例变量设定初始状态执行与对象创建相关的定制化操作。主要内容 内存分配为新对象在堆上分配足够的内存空间。实例成员变量的默认初始化所有实例变量会被自动赋予其数据类型的默认值如整型为0、浮点型为0.0、引用类型为 null 等。实例初始化块Instance Initialization Block的执行如果有实例初始化块它们会在构造器调用之前按声明顺序执行。构造器调用调用与创建对象所对应的构造器执行构造器内的初始化代码为实例变量赋予特定的初始值可能还会执行其他逻辑。 综上所述类的初始化不是对象的实例化。它们是Java类生命周期中不同阶段的两种独立行为。类初始化关注于类的静态成员及资源的初始化是针对类本身的而对象实例化则是针对类的具体实例包括为其分配内存、初始化实例变量以及可能的构造器调用。类初始化通常在程序启动初期或首次使用类时一次性完成而对象实例化则可以在程序运行过程中随时发生每次创建新对象时都会进行实例化过程。 ③以下代码的运行结果是什么 final int a final int a a Integer.valueOf(1);public class test4 {public static void main(String[] args){System.out.println(test4_A.a);} }class test4_A {public static final int a Integer.valueOf(1);static {System.out.println(test4_A的静态代码块执行);} }运行如下 ✔️分析如下 我们知道final修饰的基本数据类型的静态变量在准备阶段时会直接将代码中的值进行赋值而 int a Integer.valueOf(1)是将Integer 对象转换为其对应的原始类型 int赋值1给变量a尽管变量a是通过final修饰但在准备阶段时JVM并没有识别出变量a最终的值是基本数据类int的1它是需要执行指令才能得出结果也就是说你只有明白的告诉JVMa的值就是1final int a 1程序才不会执行test4_A的初始化 结论 final修饰的变量如果赋值的内容需要执行指令才能得出结果会执行clinit方法进行初始化 参考资料 https://www.bilibili.com/video/BV1r94y1b7eS?p11spm_id_frompageDrivervd_source5a34715e416a427a73a3ca52397848b5
http://www.hkea.cn/news/14414565/

相关文章:

  • WordPress 站点图标链接网站建设必备语言
  • 做网站需要哪些硬件网站建设好评公司
  • 有色建设网站域名的格式是什么
  • 域名备案中网站可以开通睢县房产网站建设
  • 免费网站空间哪个好哪个网站做淘宝客最合适
  • 如何做网站访百度联盟亚马逊网站如何做商家排名
  • 网站设置地图化妆品设计网站
  • 宣武富阳网站建设360优化大师最新版下载
  • 乐清站在哪成品网站建设咨询
  • 长沙网站建设大全给一个网站
  • 多肉建设网站前的市场分析网站域名到期后果
  • 邯郸手机网站建设wordpress记录阅读者ip
  • 微网站平台网站框架代码
  • 山东省建设备案网站审批表临沂网站推广
  • 如何建立公司网站怎么在亚马逊上开店铺
  • 网站建设可以修改吗海南建设银行官方网站
  • 台州建设局招标投标网站企业模拟网站建设
  • 无锡论坛网站建设连云港网站建设
  • 佛山网站的优化免费制作app平台
  • 高端平面设计网站湘潭电大网站
  • 《网页设计与网站建设》大作业要求北京app开发公司有哪些
  • 开题报告 网站建设检察院内部网站升级建设
  • 网站建设 业务走下坡高端轻奢品牌
  • 网站建设公司普遍存在劣势做涉黄的视频网站用什么服务器
  • cms网站开发流程业务型网站做seo
  • 做接口的网站想学网站设计
  • 门户网站开源一个新网站关键词怎么做SEO优化
  • 豆芽网站建设酷家乐在线设计官网
  • 江阴网站设计在线logo设计免费
  • 门户类网站前台网店制作