美文网首页
Java学习笔记二:内存分析、this、static和参数传值机

Java学习笔记二:内存分析、this、static和参数传值机

作者: 开发者连小超 | 来源:发表于2020-01-14 15:08 被阅读0次

    一、面向对象的内存分析

    1.内存分配
    • 栈的特点如下:
    1. 栈描述的是方法执行的内存模型。每个方法被调用都会创建一个栈帧(存储局部变量、操作数、方法出口等)。
    2. JVM为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数、局部变量等)。
    3. 栈属于线程私有,不能实现线程间的共享。
    4. 栈的存储特性是“先进后出”,类似弹夹。
    5. 栈是由系统自动分配,速度快,栈是一个连续的内存空间。
    • 堆的特点如下:
    1. 堆用于存储创建好的对象和数组(数组也是对象)。
    2. JVM只有一个堆,被所有线程共享。
    3. 堆是一个不连续的内存空间,分配灵活,速度慢。
    • 方法区(又叫静态区)特点如下:
    1. JVM只有一个方法区,被所有线程共享。
    2. 方法区实际也是堆,只是用于存储类、常量相关的信息。
    3. 用来存放程序中永远是不变或唯一的内容。(类信息【Class对象】、静态变量、字符串常量等)
    内存分配.png

    以下代码为例,绘制内存执行图

    public class SxtStu {
        int  id;
        String  sname;
        int  age;
        Computer  comp;
    
        void  study(){
            System.out.println("我在认真学习!!,使用电脑:"+comp.brand);
        }
        void  play(){
            System.out.println("我在玩游戏!王者农药!");
        }
    
        public static void main(String[] args) {
            SxtStu  stu = new SxtStu();
            stu.id=1001;
            stu.sname= "高淇";
            stu.age = 18;
    
            Computer  c1 = new Computer();
            c1.brand = "联想";
            stu.comp = c1;
    
            stu.play();
            stu.study();
        }
    }
    
    class  Computer {
        String  brand;
    }
    
    图片.png

    二、构造方法

    1.构造方法解释

    构造器也叫构造方法(constructor),用于对象的初始化。构造器是一个创建对象时被自动调用的特殊方法,目的是对象的初始化。构造器的名称应与类的名称一致。Java通过new关键字来调用构造器,从而返回该类的实例,是一种特殊的方法。

    2.构造方法重载
    public class User {
        int id; // id
        String name; // 账户名
        String pwd; // 密码
        public User() {
     
        }
        public User(int id, String name) {
            super();
            this.id = id;
            this.name = name;
        }
        public User(int id, String name, String pwd) {
            this.id = id;
            this.name = name;
            this.pwd = pwd;
        }
        public static void main(String[] args) {
            User u1 = new User();
            User u2 = new User(101, "高小七");
            User u3 = new User(100, "高淇", "123456");     
        }
    }
    

    三、this关键字

    this的本质就是“创建好的对象的地址”,由于在构造方法调用前,对象已经创建。因此,在构造方法中也可以使用this代表“当前对象” 。

    this最常的用法:

    1. 在程序中产生二义性之处,应使用this来指明当前对象;普通方法中,this总是指向调用该方法的对象。构造方法中,this总是指向正要初始化的对象。
    2. 使用this关键字调用重载的构造方法,避免相同的初始化代码。但只能在构造方法中用,并且必须位于构造方法的第一句。
    3. this不能用于static方法中。

    四、static 关键字

    在类中,用static声明的成员变量为静态成员变量,也称为类变量。 类变量的生命周期和类相同,在整个应用程序执行期间都有效。它有如下特点:

    1. 为该类的公用变量,属于类,被该类的所有实例共享,在类被载入时被显式初始化。
    2. 对于该类的所有对象来说,static成员变量只有一份,被该类的所有对象共享。
    3. 一般用“类名.类属性/方法”来调用。(也可以通过对象引用或类名(不需要实例化)访问静态成员。)
    4. 在static方法中不可直接访问非static的成员。

    核心要点:

    • static修饰的成员变量和方法,从属于类。
    • 普通变量和方法从属于对象的。

    代码示例:

    /**
     * 测试static关键字的用法
     */
    public class User2 {
        int id; // id
        String name; // 账户名
        String pwd; // 密码
         
        static String company = "北京尚学堂"; // 公司名称
         
        public User2(int id, String name) {
            this.id = id;
            this.name = name;
        }
         
        public void login() {
            printCompany();
            System.out.println(company); 
            System.out.println("登录:" + name);
        }
         
        public static void printCompany() {
            //login();//调用非静态成员,编译就会报错
            //System.out.println(this.id); //调用非静态成员变量,编译就会报错
            System.out.println(company);
        }
         
        public static void main(String[] args) {
            User2 u = new User2(101, "高小七");
            User2.printCompany();
            User2.company = "北京阿里爷爷";
            User2.printCompany();
        }
    }
    
    代码示例解析.png

    如上图所示,printCompany()方法调用login()方法就会报错,因为方法区里找不到login()方法;而login()可调用printCompany()方法。同理printCompany()方法里也无法调用id,name成员变量。

    四、静态初始化块

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

    静态初始化块执行顺序:

    1. 上溯到Object类,先执行Object的静态初始化块,再向下执行子类的静态初始化块,直到我们的类的静态初始化块为止。而且由于类先加载,再执行构造方法初始化对象,所以静态初始化先于构造方法。
    2. 构造方法上溯执行顺序和上面顺序一样。
    public class User {
        int id;        //id
        String name;   //账户名
        String pwd;   //密码
        static String company; //公司名称
        static {
            System.out.println("执行类的初始化工作");
            company = "北京尚学堂";
            printCompany();
        }
        public static void printCompany(){
            System.out.println(company);
        }
        public static void main(String[] args) {
            User  u3 = new User();
        }
    }
    

    五、参数传值机制

    Java中,方法中所有参数都是“值传递”,也就是“传递的是值的副本”。 也就是说,我们得到的是“原参数的复印件,而不是原件”。因此,复印件改变不会影响原件。

    相关文章

      网友评论

          本文标题:Java学习笔记二:内存分析、this、static和参数传值机

          本文链接:https://www.haomeiwen.com/subject/xurnactx.html