清明休假第一天-内存分析,构造方法,虚拟机内存模型,继承,重写,this,static,final关键字

内存分析

栈stack 主方法,对象的地址,局部变量
堆heep 对象,成员变量,普通方法
方法区 method area 类信息,常量池,static修饰的属性和方法(main方法,静态变量)
清明休假第一天-内存分析,构造方法,虚拟机内存模型,继承,重写,this,static,final关键字_第1张图片

构造方法

对象的初始化
结构 [修饰符]类名(形参列表){//语句}

清明休假第一天-内存分析,构造方法,虚拟机内存模型,继承,重写,this,static,final关键字_第2张图片

JVM虚拟机内存模型以及垃圾回收机制

清明休假第一天-内存分析,构造方法,虚拟机内存模型,继承,重写,this,static,final关键字_第3张图片
栈 stack

  1. 栈描述的是方法执行的内存模型。每个方法被调用都会创建一个栈帧(存储局部变 量、操作数、方法出口等)
  2. JVM 为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数、局部变 量等)
  3. 栈属于线程私有,不能实现线程间的共享!
  4. 栈的存储特性是“先进后出,后进先出”
  5. 栈是由系统自动分配,速度快!栈是一个连续的内存空间!

堆 heep

  1. 堆用于存储创建好的对象和数组(数组也是对象)
  2. JVM 只有一个堆,被所有线程共享
  3. 堆是一个不连续的内存空间,分配灵活,速度慢!
  4. 堆被所有的线程所共享,在堆上的区域,会被垃圾回收器做进一步划分,例如新生 代、老年代的划分。

方法区 method area

  1. 方法区是 JAVA 虚拟机规范,可以有不同的实现。
    i. JDK7 以前是“永久代”
    ii. JDK7 部分去除“永久代”,静态变量、字符串常量池都挪到了堆内存中
    iii. JDK8 是“元数据空间”和堆结合起来。
  2. JVM 只有一个方法区,被所有线程共享!
  3. 方法区实际也是堆,只是用于存储类、常量相关的信息!
  4. 用来存放程序中永远是不变或唯一的内容。(类信息【Class 对象,反射机制中会 重点讲授】、静态变量、字符串常量等)
  5. 常量池主要存放常量:如文本字符串、final 常量值。

垃圾回收机制
清明休假第一天-内存分析,构造方法,虚拟机内存模型,继承,重写,this,static,final关键字_第4张图片
GC收回器对应的区域
·Minor GC: 用于清理年轻代区域。Eden 区满了就会触发一次 Minor GC。清理无用对象,将有用 对象复制到“Survivor1”、“Survivor2”区中。
·Major GC: 用于清理老年代区域。
·Full GC: 用于清理年轻代、年老代区域。 成本较高,会对系统性能产生影响。

this关键字(当前对象的本身,对象的地址)

普通方法中,this总是指向调用该对象
构造方法中,this总是指向正在初始化的对象## static的本质

static关键字

静态变量(类变量),静态方法(类方法)

静态变量/静态方法生命周期和类相同,在整个程序执行期间都有效。它有如下特点:
 为该类的公用变量,属于类,被该类的所有实例共享,在类载入时被初始化。
 static 变量只有一份。
 一般用“类名.类变量/方法”来调用。
 在 static 方法中不可直接访问非 static 的成员。

静态初始化块 结构–>static{//代码块}

构造方法用于对象的普通属性初始化。
静态初始化块,用于类的初始化操作,初始化静态属性。
在静态初始化块中不能直接访问非 static 成员。

package和import

包(package)

相当于文件夹对于文件的作用。用于管理类、用于解决类的重名问题。
packag的使用有两个要点:

  1. 通常是类的第一句非注释性语句。
  2. 包名:域名倒着写即可,便于内部管理类。

导入(import)

如果要使用其他包的类,需使用 import,从而在本类中直接通过类名来调用,否则就 需要书写类的完整包名和类名。
注意要点
 Java 会默认导入 java.lang 包下所有的类,因此这些类我们可以直接使用。
 如果导入两个同名的类,只能用包名+类名来显示调用相关类: java.util.Date date = new java.util.Date();

静态导入

静态导入(static import): 其作用是用于导入指定类的静态属性和静态方法,这样我 们可以直接使用静态属性和静态方法。

package com.itbaizhan; 
import static java.lang.Math.*;//导入Math类的所有静态属性 
import static java.lang.Math.PI;//导入Math类的PI属性 
public class Test2{ 
public static void main(String [ ] args){ 
    System.out.println(PI);  
    System.out.println(random()); 
}

面向对象的三大特征-继承

/**
 * TestExtends class
 *  1. 父类也称作超类、基类。 子类:派生类等。
 *  2. Java 中只有单继承,没有像 C++那样的多继承。多继承会引起混乱,使得继承链 过于复杂,系统难于维护。
 *  3. Java 中类没有多继承,接口有多继承。
 *  4. 子类继承父类,可以得到父类的全部属性和方法 (除了父类的构造方法),但不见得可以直接访问(比如,父类私有的属性和方法)。
 *  5. 如果定义一个类时,没有调用 extends,则它的父类是:java.lang.Object。
 * @author Huanghao
 * @date 2022/04/03
 */
public class TestExtends {
    public static void main(String[] args) {
        Student s1 = new Student("huanghao",175,"java");
        System.out.println(s1.name);
        s1.study();
        //instanceof 是二元运算符,左边是对象,右边是类;
        // 当对象是右面类或子类所创建对象时,返回 true;否则,返回 false。
        System.out.println(s1 instanceof Student);
        System.out.println(s1 instanceof Person);
    }
}

/**
 * 任何一个类如果没有写继承,都天然的继承Object
 */
class Person /*extends Object*/{
    String name;
    int height;

    public void rest() {
        System.out.println("休息一会!");
    }
}

class Student extends Person {
    String major;

    public void study() {
        System.out.println("学习Java");
        rest();
        System.out.println(this.name);
    }

    public Student(String name, int height, String major) {
        //天然拥有父类的属性
        this.name = name;
        this.height = height;
        this.major = major;
    }
}

class Boy extends Person{

}

重写,继承和组合的区别

/**
 * TestOverride class
 * override 子类重写父类的方法,可以用自身行为替换父类行为。重写是实现多态的必要条件。
 * 1. “= =”: 方法名、形参列表相同。
 * 2. “≤”:返回值类型和声明异常类型,子类小于等于父类。
 * 3. “≥”: 访问权限,子类大于等于父类。
 * @author Huanghao
 * @date 2022/04/03
 */
public class TestOverride {
    public static void main(String[] args) {
        Honor h = new Honor();
        h.run();
        h.getVehicle();
    }
}
class Vehicle{
    public void run(){
        System.out.println("跑跑跑...");
    }
    public Honor getVehicle(){
        System.out.println("给你一个交通工具");
        return null;
    }
}
class Honor extends Vehicle{
    @Override
    public void run() {
        System.out.println("得得得......");
    }

    @Override
    public Honor getVehicle() {
        System.out.println("真快啊.....");
        return null;
    }
}
class Plane extends Vehicle{
    @Override
    public void run() {
        System.out.println("天上飞......");
    }

}

/**
 * TestComponent class
 *  测试组合
 *  对于“is -a”关系建议使用继承,“has-a”关系建议使用组合。
 * @author Huanghao
 * @date 2022/04/03
 */
public class TestComponent {
    public static void main(String[] args) {
        Student2 s1 = new Student2("huanghao",175,"java");
//        System.out.println(s1.name);
        s1.study();
        System.out.println(s1 instanceof Student2);
//        System.out.println(s1 instanceof Person2);
    }
}

class Person2 {
    String name;
    int height;

    public void rest() {
        System.out.println("休息一会!");
    }
}

class Student2 {
    String major;
    Person2 p = new Person2();
    public void study() {
        System.out.println("学习Java");
        System.out.println(this.p.name);
        p.rest();
        System.out.println(this.p.name);
    }

    public Student2(String name, int height, String major) {
        //天然拥有父类的属性
        this.p.name = name;
        this.p.height = height;
        this.major = major;
    }
}

class Boy2 extends Person2{

}

final关键字的使用

/**
 * TestFinal class
 * 测试final
 *  修饰变量: 被他修饰的变量不可改变。一旦赋了初值,就不能被重新赋值。 final int MAX_SPEED = 120;
 *  修饰方法:该方法不可被子类重写。但是可以被重载! final void study(){}
 *  修饰类: 修饰的类不能被继承。比如:Math、String 等。 final class A {}
 *
 * @author Huanghao
 * @date 2022/04/03
 */
public class TestFinal {
    public static void main(String[] args) {
        Pet p = new Pet();
        p.get();
    }
}

class Pet {
    public /*static*/ void get() {
        System.out.println("请不要动我");
    }
}

class Dog extends Pet {
    @Override
    public void get() {
        System.out.println("你在狗叫什么啊");
    }
}

你可能感兴趣的:(java)