0
点赞
收藏
分享

微信扫一扫

java基础 Day13

笙烛 2022-04-18 阅读 74

一、类加载机制

类的完整生命周期 :加载、连接(验证、准备、解析、初始化)、使用、卸载
一、加载
1.通过一个类的全限定名来获取其定义的二进制字节流
2. 将这个字节流所代表的的静态存储结构转化为方法区的运行时数据结构
3. 在堆中生成一个代表这个类的Class对象,作为方法区中这些数据的访问入口
4. 注意: 相对于类加载过程的其他阶段而言,加载阶段是可控性最强的阶段,因为程序员可以使用系统的类加载器加载,还可以使用自己的类加载器加载,在这里我们只需要知道类加载器的作用就是上面虚拟机需要完成的三件事
二、连接
1.验证
文件格式验证,元数据验证,字节码验证,符号引用验证。
注意:对整个类加载机制而言,验证阶段是一个很重要但是非必需的阶段,如果我们的代码能够确保没有问题,那么我们就没有必要去验证,毕竟验证需要花费一定的的时间。当然我们可以使用
-Xverfty:none来关闭大部分的验证。
2.准备 - 重要
----准备阶段主要为类变量(static)分配内存并设置初始值。这些内存都在方法区分配。在这个阶段我们只需要注意两点就好了,类变量和初始值两个关键词:

  • 类变量(static):会分配内存,但不会对应的分配值,其次实例变量不会分配空间,因为实例变量主要随着对象的实例化一块分配到java堆内存中
  • 初始值:这里的初始值指的是数据类型默认值,而不是代码中被显示赋予的值

3.解析
解析阶段主要是虚拟机将常量池中的符号引用转化为直接引用的过程

  • 符号引用:以一组符号来描述所引用的目标,可以是任何形式的字面量,只要是能无歧义的定位到目标就好,就好比在班级中,老师可以用张三来代表你,也可以用你的学号来代表你,但无论任何方式这些都只是一个代号(符号),这个代号指向你(符号引用)
  • 直接引用:直接引用是可以指向目标的指针、相对偏移量或者是一个能直接或间接定位到目标的句柄。和虚拟机实现的内存有关,不同的虚拟机直接引用一般不同
  • 补充: 解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符7类符号引用进行

4.初始化
这是类加载机制的最后一步,在这个阶段,java程序代码才开始真正执行。在准备阶段已经为类变量赋过一次值。在初始化阶端,程序员可以根据自己的需求来赋值了
在初始化阶段,主要为类的静态(stitic)变量赋予正确的初始值,JVM负责对类进行初始化,主要对类变量(stitic)进行初始化。在Java中对类变量进行初始值设定有两种方式:
-----声明类变量时指定初始值
----- 使用静态代码块为类变量指定初始值

三、使用: 当 JVM 完成初始化阶段之后,JVM 便开始从入口方法开始执行用户的程序代码

四、卸载: 当用户程序代码执行完毕后,JVM 便开始销毁创建的 Class 对象,最后负责运行的 JVM 也退出内存

二、static关键字

static修饰方法
含义:静态方法
理解:静态方法属于类的方法,直接使用类名调用即可
应用场景:工具类(Arrays)

static 修饰属性
含义:静态属性
理解:静态属性属于类的属性,直接使用类名调用即可
生命周期:
1.类的字节码文件加载到方法区时,系统会扫描该类的静态属性,并把静态属性加载到静态区中
2.项目结束时,静态属性才会被销毁
-----类的字节码文件何时被加载到方法区中?
* 答:使用到该类时,就会把该类的字节码文件加载到方法区中
* 情况一:new该类的对象
* 情况二:调用该类的静态方法
* 情况三:获取该类的class对象

static 修饰代码块
静态代码块:可以初始化静态变量
注意:类加载到方法区时,调用静态代码块(静态代码块优先于创建对象,所以静态代码块中不能初始化成员变量)

三、继承 (extends)

应用场景:在需求分析时,分析出多个类有共同的属性和方法时,就将共同的属性和方法抽取到父类里
关键字:extends
A.java

public class A {
	
	private String str1 = "父类私有化成员变量";
	
	//注意:静态变量属于类的变量,不能被子类继承
	private static String str2 = "父类私有化静态变量";
	
	public A(){
		System.out.println("父类的构造方法");
	}
	
	public void method01(){
		System.out.println(str1);
		System.out.println(str2);
	}
	
	private void method02(){
		System.out.println("父类私有化成员方法");
	}
	
	public void method03(){
		method02();
		method04();
	}
	
	private  static void method04(){
		System.out.println("父类私有化静态方法");
	}
}

B.java

public class B extends A{

	public B() {
		//super();//默认实现,调用父类的无参构造
		System.out.println("子类的构造方法");
		
	}
	
}

Test01.java

public class Test01 {
	/**
	 * 知识点:深入继承
	 * 
	 * 1.创建子类对象时,是否会调用父类构造方法?
	 * 		会的
	 * 2.创建子类对象时,是否会创建父类对象?
	 * 		不会
	 * 3.创建子类对象时,调用父类的构造方法的目的是什么?
	 * 		将父类的成员变量添加到子类对象中(内存图)
	 * 4.创建子类对象时,先调用父类构造方法还是子类构造方法?
	 * 		先调用子类的构造方法
	 * 5.创建子类对象时,先完成父类构造方法还是子类构造方法?
	 * 		先完成父类构造方法
	 * 6.子类是否可以继承父类的私有化属性和方法
	 * 		父类的静态属性和静态方法不能被子类继承,因为静态属性和静态方法是类的属性和方法
	 * 		父类所有的成员属性和成员方法可以被子类所继承,
	 * 		但是私有化成员属性和成员方法方法不能直接调用,但是可以间接调用(在父类中设置公有化方法,在公有化方法中调用私有的属性和方法)
	 */
	public static void main(String[] args) {
		B b = new B();
		b.method01();
		b.method03();
	}
}
输出:
父类的构造方法
子类的构造方法
父类私有化成员变量
父类私有化静态变量
父类私有化成员方法
父类私有化静态方法

四、super

父类的
作用:
* 1.super.属性:在子类中调用父类的非私有化的成员变量
* 2.super.方法:在子类中调用父类的非私有化的成员方法
* 3.super():在子类中调用父类的非私有化的构造方法

五、重写/复写

含义:在子类中重写父类的方法
应用场景:父类方法不能改动时并且父类方法不满足子类需求,可以考虑使用重写
条件:
1.在子类中重写父类的方法
2.返回值类型、方法名、参数列表必须和父类重写的方法一模一样
3.访问修饰符不能比父类的更严格

@Override 该注解在方法上表明该方法时重写父类的方法

举报

相关推荐

JS基础day13

寒假Java学习Day13:

Java学习记录day13

寒假:Day13

JVM[day13]

爬虫笔记day13

算法练习-day13

云计算day13

0 条评论