day05-面向对象内存原理和数组

day05 面向对象内存原理和数组

我们在之前已经学习过创建对象了,那么在底层中他是如何运行的。

1.对象内存图

1.1 Java 内存分配

Java 程序在运行时,需要在内存中分配空间。为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。

在这里插入图片描述

在这里插入图片描述

Cat cat = new Cat();

突出了解对于堆栈的学习。

1.2 堆和栈

:所有局部变量都会在栈内存中创建
局部变量:定义在方法中的变量或者方法声明上的变量

方法执行都会加载到栈中进行

局部变量特点:随着方法的调用而存在,随着方法的调用完毕而消失

代码:Student s = new Student();
:所有对象及其对应的实例变量和数组都将存储在此处
简单理解为:new出来的东西,都存储在堆内存
每一个new出来的东西都有一个地址值,使用完毕,会在垃圾回收器空闲时被回收
实例变量(成员变量)有初始化值:
基本数据类型:整数:0,浮点数:0.0,布尔:false,字符:空字符
引用数据类型:null

成员变量和局部变量的区别

区别成员变量局部变量
类中位置不同类中方法外方法内或者方法声明上
内存中位置不同堆内存栈内存
生命周期不同随着对象的存在而存在,随着对象的消失而消失随着方法的调用而存在,随着方法的调用完毕而消失
初始化值不同有默认的初始化值没有默认的初始化值,必须先定义,赋值,才能使用
单个对象 指向一个地址

多个对象 指向对应数量的多个地址

多个引用指向相同  地址可以为同一个

1.3 堆-栈内存总结

1.new 对象会创建堆内存
2.声明变量 只创建栈内存
3.多个变量可以指向一个对象
4.局部变量存在栈内存,用完就消失,作用范围仅限方法或者局部{}范围
5.成员变量会存在堆内存,随着对象消失才消失,作用范围类范围

2.private

是一个权限修饰符
可以修饰成员(成员变量和成员方法)
作用是保护成员不被别的类使用,被 private 修饰的成员在本类中可以通过 实例对象.属性名进行访问。

针对 private 修饰的成员变量,如果需要被其他类使用,提供两个相应的操作:
提供“get变量名()”方法,用于获取成员变量的值,方法用 public 修饰
提供“set变量名(参数)”方法,用于设置成员变量的值,方法用 public 修饰

eg:

public class Student {
    private String name;
    public String getName() {
        return name;   
        }
    public void setName(String name) {
        this.name = name;
    }
    //被 private 修饰的成员在本类中可以通过实例对象.属性名进行访问
    public static void main(String[] args) {
        Student student = new Student();
        System.out.println(student.name);
    }
}
public class People {
    public static void main(String[] args) {
        Student student = new Student();
        System.out.println(student.name);//报错!!
    }
}

3.this

this:方法被哪个对象调用,this就代表哪个对象。

① 什么时候使用this呢?

解决局部变量隐藏成员变量

局部变量和成员变量名字一致,局部变量赋值给成员变量。

② this限定的变量用于指代成员变量

方法的形参如果与成员变量同名,
不带this修饰的变量指的是形参,而不是成员变量
方法的形参没有与成员变量同名,
不带this修饰的变量指的是成员变量

public class Student { 
	private String name;  
	public String getName() {
        return name;   
        }
    public void setName(String name) {
        this.name = name;
    }
}
 public void setName(String username) {
        name = username;//这里可以不用this
    }

4.封装

1.封装概述

是面向对象三大特征之一(封装,继承,多态
是面向对象编程语言对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外界是无法直接操作的

eg:相当于把水放在一个水杯中,只能通过水杯出水口喝水。 外界是无法拿到水,只能通过一个公共的出口取水。

2.封装原则

将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问
成员变量private,提供对应的**getXxx()/setXxx()**方法

3.封装好处

通过方法来控制成员变量的操作,提高了代码的安全性
把代码用方法进行封装,提高了代码的复用性

规范代码:

public class Student {
	private String name;
	public String getName() {
        return name;
        }
    public void setName(String name) {
        this.name = name;
    }

    private int age;
    public int getAge() {
        return age;    }
    public void setAge(int age) {
        this.age = age;
    }
}

快捷方式:alt+insert 选择getterAndSetter

5.构造方法

5.1 构造方法概述

构造方法是一种特殊的方法

作用:创建对象

格式:

public class 类名{        

修饰符 类名(参数) {       

 }}

功能:主要是完成对象数据的初始化

5.2 构造方法的注意事项

① 构造方法的创建

如果没有定义构造方法,系统将给出一个默认无参数构造方法
如果定义了构造方法,系统将不再提供默认的构造方法

② 构造方法的重载

如果自定义了带参构造方法,还要使用无参数构造方法,就必须再写一个无参数构造方法

③ 推荐的使用方式

永远提供无参数构造方法

5.3 JavaBean

就是一个Java中的类,其对象可以用于在程序中封装数据
举例:学生类,手机类

标准 JavaBean 须满足如下要求:
1.成员变量使用 private 修饰
2.提供每一个成员变量对应的 setXxx() / getXxx()
3.提供一个无参构造方法

5.4 练习

手机 JavaBean

需求:编写手机 JavaBean,并在测试类中使用
提示:手机有成员变量brand(品牌)和price(价格)

6.数组

数组概述

为了存储一个学员的考试成绩,我们可以采用一个变量进行存储,如果我有很多个学员的考试成绩,我们也可以用多个变量进行存储。但是,如果学员人数太多,这样定义变量就太麻烦了,这就对我们存储数据提出了新的诉求:一次性声明大量的用于存储数据的变量,要存储的数据通常都是同类型数据,例如:考试成绩。满足这种诉求的东西是什么呢?就是我们接下来要讲解的数组。来我们说一下什么是数组。

int a = 100int b = 100int c = 100int d = 100int e = 100int f = 100int g = 100… …

在这里插入图片描述

一次性声明大量的用于存储数据的变量

要存储的数据通常都是同类型数据,

例如:考试成绩int[] scores = {100,100,100,100,100,100,100…};

什么是数组

数组(array):是一种用于存储多个相同数据类型的存储模型(可以理解为容器)

1.数组定义格式

格式1数据类型[] 变量名;
范例: int[] arr;
定义了一个int类型的数组,数组名是arr

格式2数据类型 变量名**[];
范例: int arr
[]**;
定义了一个int类型的变量,变量名是arr数组

推荐使用:格式1

2.数组初始化概述

静态初始化
动态初始化

2.1.数组初始化之静态初始化

静态初始化:初始化时指定每个数组元素的初始值,由系统决定数组长度

格式:数据类型[] 变量名 = new 数据类型[]{数据1,数据2,数据3,…};

范例:int[] arr = new int[]{1,2,3};

简化格式:数据类型[] 变量名 = {数据1,数据2,数据3,…};

范例:int[] arr = {1,2,3};

2.2 数组初始化之动态初始化

动态初始化:初始化时只指定数组长度,由系统为数组分配初始值

格式:数据类型[] 变量名 = new 数据类型[数组长度];

范例:int[] arr = new int[3];

使用场景:
静态初始化:开始就存入元素值,适合一开始就能确定元素值的业务场景
动态初始化:指定数组长度,后期赋值,适合开始知道数据的数量,但是不确定具体元素值的业务场景
注意:两种初始化的方式是独立的,不可以混用

int[] arr = new int[3]{30,40,50}; //错!!!!

2.3 数组元素来自键盘录入

需求:定义一个可以存储5个元素的int数组,数据来自于键盘录入,最后遍历数组,把元素输出在控制台

分析:
① 数组长度可知,元素未知,采用动态初始化
② 键盘录入,使用Scanner实现

eg:

 public static void main(String[] args) {
        int[]arr = new int[5];
        Scanner sc = new Scanner(System.in);

        for (int j = 0; j < 5; j++) {
            System.out.println("请输入第" + (j+1) + "个数");
            arr[j] = sc.nextInt();
        }
        printArray(arr);
    }
    public static void printArray(int[] arr) {
        System.out.print("[");
        for (int i = 0; i < arr.length; i++) {
            if(i==arr.length-1) {
                System.out.print(arr[i]);
            }else {
                System.out.print(arr[i] + ", ");
            }
        }
        System.out.println("]");
    }

3.数组元素访问

3.1 数组变量访问方式
格式:数组名
3.2 数组内部保存的数据的访问方式
格式:数组名[索引]
3.3 索引是数组中数据的编号方式

作用:索引用于访问数组中的数据使用,数组名[索引]等同于变量名,是一种特殊的变量名
特征①:索引从0开始
特征②:索引是连续的
特征③:索引逐一增加,每次加1

4.数组常见操作

4.1遍历

什么是数组遍历
获取数组中的每一个元素,我们可以把获取到的元素输出在控制台

获取数组长度(元素个数)

格式:数组名.length

范例:arr.length

数组遍历通用格式:

int[] arr = {...};
for (int i = 0; i < arr.length; i++) { 
arr[i]; //对元素arr[i]进行操作
}

注意:数组遍历指的是把数组中的元素取出来,取出来之后可以(打印,求和,判断…)

4.2 获取最大值

在这里插入图片描述
获取数组中最大值

  public static void main(String[] args) {
        //定义数组
        int[] arr = {12, 45, 98, 73, 60};

        //定义变量max存储最大值,取第一个数据为变量的初始值
        int max = arr[0];

        //与数组中剩余数据逐个比对,每次比对将最大值保存到变量max中
        for (int i=1; i<arr.length; i++) {
            if(arr[i] > max) {
                max = arr[i];
            }
        }

        //循环结束后输出变量max的值
        System.out.println("max:" + max);
    }

4.3 元素打乱

把数组中的元素随机交换位置,每次运行都可能产生不一样的结果
比如:arr = {12, 45, 98, 73, 60};
遍历:
正常情况下:12,45,98,73,60
元素打乱后:45,73,12,60,98
涉及到的操作
获取数组中元素的随机索引

Random r = new Random();
int index = r.nextInt(arr.length);

数组中元素交换

int a = 10;
int b = 20;
int temp = a;
a = b;
b = temp;
System.out.println(a);
System.out.println(b);

元素打乱案例

public static void main(String[] args) {
        //定义数组
        int[] arr = {12, 45, 98, 73, 60};

//        Random r = new Random();
//        int index = r.nextInt(arr.length);
//
//        //第一次交换
//        int temp = arr[0];
//        arr[0] = arr[index];
//        arr[index] = temp;
//
//        //第二次交换
//        index = r.nextInt(arr.length);
//        temp = arr[1];
//        arr[1] = arr[index];
//        arr[index] = temp;

        Random r = new Random();
        for (int i = 0; i < arr.length; i++) {
            int index = r.nextInt(arr.length);

            int temp = arr[i];
            arr[i] = arr[index];
            arr[index] = temp;
        }
        //遍历数组
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }

5.思考问题数组常见问题

请问下列代码有问题吗?

int[] arr = new int[3];//输出元素
System.out.println(arr[3]);

如果有,是什么问题?

如何解决?

有问题访问了不存在的索引位置元素修改不存在的索引为正确的索引。范围(0~数组长度-1)

int[] arr = new int[3];
System.out.println(arr[2]);//把 null赋值给数组
arr = null;// 输出元素
System.out.println(arr[0]);
数组使用中的两个小问题
    1:索引越界:访问了数组中不存在的索引对应的元素,造成索引越界问题
        ArrayIndexOutOfBoundsException

    2:空指针异常:对象不再指向堆内存,还想继续访问数据,访问失败
        NullPointerException

    null:空值,引用数据类型的默认值,表示不指向任何有效对象

6.二维数组(自学作业)

需求:我们要存储多个班级的学生的考试成绩,该怎么办呢?
如果要存储一个班级中多个学生的考试成绩,我们就可以采用数组来存储。
多个班级的考试成绩,我们针对每个班级都采用数组存储:
第一个班级:数组1
第二个班级:数组2
第三个班级:数组3

但是多个班级也可以采用数组存储啊?所以,Java就提供了二维数组供我们使用

6.1二维数组概述

二维数组:元素为一维数组的数组

定义格式:

数据类型[][] 变量名;	int[][] arr;//重点	
数据类型 变量名[][];	int arr[][];
数据类型[] 变量名[];	int[] arr[];

6.2二维数组初始化

6.21静态初始化

1.格式:

数据类型[][] 变量名 = new 数据类型[][]{{元素…},{元素…},{元素…},…};

2.范例:

int[][] arr = new int[][]{{1,2,3},{4,5,6},{7,8,9}};

3.解读

定义了一个二维数组
二维数组中有三个元素(一维数组)
每一个一维数组有三个元素(int类型数据)

4.注意:一维数组中元素的个数可以是不同的

举例: int[][] arr = new int[][]{{1,2,3},{4,5},{6,7,8,9}};

5.简化格式:

数据类型[][] 变量名 = {{元素…},{元素…},{元素…},…};

6.范例:

int[][] arr = {{1,2,3},{4,5,6},{7,8,9}};
6.22 动态初始化

1.格式:

数据类型[][] 变量名 = new 数据类型[m][n];

2.范例:

int[][] arr = new int[2][3];

3.解读

定义了一个二维数组
二维数组中有2个元素(一维数组)
每一个一维数组有3个元素(int类型数据)
6.23 二维数组元素访问
获取二维数组:数组名
获取每一个一维数组:数组名[索引]  从0开始
获取每一个二维数组元素:数组名[索引][索引]  从0开始
6.24 二维数组常见操作

遍历&元素打乱

1.二维数组遍历

需求:已知一个二维数组 arr = {{1,2,3},{4,5,6},{7,8,9}}; 请把元素在控制台输出
二维数组中循环嵌套的使用:
① 循环嵌套:循环语句中嵌套循环语句
② 外层循环得到一维数组
③ 内存循环得到每一个二维数组元素
 public static void main(String[] args) {
        int[][]arr = {{1,2,3},{4,5,6},{7,8,9}};
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr.length; j++) {
                System.out.println(arr[i][j]);
            }
        }
    }

2.二维数组元素打乱

需求:已知二维数组 arr = {{1,2,3},{4,5,6},{7,8,9}};
用程序实现把数组中的元素打乱,并在控制台输出打乱后的数组元素
public static void main(String[] args) {
        int[][]arr = {{1,2,3},{4,5,6},{7,8,9}};
        Random r = new Random();
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr.length; j++) {
                //arr[i][j]
                int a = r.nextInt(arr.length);
                int b = r.nextInt(arr.length);
                //元素交换
                int temp = arr[i][j];
                arr[i][j] = arr[a][b];
                arr[a][b]= temp;
            }
        }
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr.length; j++) {
                System.out.print(arr[i][j]+" ");
            }
        }
    }
    int[][]arr = {{1,2,3},{4,5,6},{7,8,9}};
    Random r = new Random();
    for (int i = 0; i < arr.length; i++) {
        for (int j = 0; j < arr.length; j++) {
            //arr[i][j]
            int a = r.nextInt(arr.length);
            int b = r.nextInt(arr.length);
            //元素交换
            int temp = arr[i][j];
            arr[i][j] = arr[a][b];
            arr[a][b]= temp;
        }
    }
    for (int i = 0; i < arr.length; i++) {
        for (int j = 0; j < arr.length; j++) {
            System.out.print(arr[i][j]+" ");
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/616875.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯-地宫取宝

X 国王有一个地宫宝库&#xff0c;是 nm 个格子的矩阵&#xff0c;每个格子放一件宝贝&#xff0c;每个宝贝贴着价值标签。 地宫的入口在左上角&#xff0c;出口在右下角。 小明被带到地宫的入口&#xff0c;国王要求他只能向右或向下行走。 走过某个格子时&#xff0c;如果那个…

睿尔曼机械臂ROS控制

下载git工程 git clone https://github.com/RealManRobot/rm_robot.git安装配置 catkin build rm_msgs source devel/setup.bash catkin build source setup.bash这里注意&#xff0c;如果采用setup.sh多半不会成功&#xff0c;必须要source setup.bash文件&#xff0c;ros才…

数据分析思维——数据埋点笔记,以电商为例

数据埋点 数据分析前提是有数据&#xff0c;数据从哪里来&#xff0c;要选择采集哪些数据都需要考虑。如某些app上的商品推荐&#xff0c;是基于哪些信息来预判的呢&#xff1f;因此作为数据分析师有必要系统的了解用户行为到用户数据的整个过程 何为数据埋点 每当用户在客户端…

JeeSite V5.7.0 发布,Java快速开发平台,Vite5、多项重构重磅升级

JeeSite V5.7.0 发布&#xff0c;Java快速开发平台&#xff0c;Vite5、多项重构重磅升级 升级内容 新增 参数配置 IP 地址黑白名单过滤器动态参数 新增 侧边栏是否展开第一个菜单的开关 first-open 新增 AesTypeHandler 处理字段数据加密解密或脱敏 新增 JsonTypeHandler …

FANUC机器人坐标系的分类和简介

1、概述 坐标系是为了确定机器人的位置和姿势而在机器人或空间上定义的位置指标系统&#xff0c;坐标系分为关节坐标系和直角坐标系&#xff0c;直角坐标系遵循右手定则&#xff0c;而关节坐标系则是以机器人每个轴所转动的角度来表示机器人当前的位置。 2、坐标系的分类及简…

2024 年最新本地、云服务器安装部署 miniconda 环境详细教程(更新中)

Anaconda 概述 Anaconda 是专门为了方便使用 Python 进行数据科学研究而建立的一组软件包&#xff0c;涵盖了数据科学领域常见的 Python 库&#xff0c;并且自带了专门用来解决软件环境依赖问题的 conda 包管理系统。主要是提供了包管理与环境管理的功能&#xff0c;可以很方便…

嵌入式全栈开发学习笔记---C语言笔试复习大全15

目录 指针运算 笔试题17 思考&#xff1a;*px、*px和(*px)的区别&#xff01; 笔试题18 补充命令8&#xff1a;“cd ..”退回到上一级目录 补充命令9&#xff1a;“man 3 函数名”可以查看库函数的原型 const 修饰指针是什么意思&#xff1f;&#xff08;笔试重点&#…

用hMailServer+roundcubemail+宝塔安装配置一个自己的邮箱服务

用hMailServerroundcubemail安装配置一个自己的邮箱服务 1、准备工具与资料&#xff1a; 云服务器一台 基础配置就行 2核4G。域名一个 以下用lizipro.cn示例。hMailServer安装包roundcubemail安装包异常处理插件补丁&#xff1a; libmysql.zip 2、hMailServer服务安装&#…

QToolButton的特殊使用

QToolButton的特殊使用 介绍通过QSS取消点击时的凹陷效果点击时的凹陷效果通过QSS取消点击时的凹陷效果 介绍 该篇文章记录QToolButton使用过程中的特殊用法。 通过QSS取消点击时的凹陷效果 点击时的凹陷效果 通过QSS取消点击时的凹陷效果 #include <QToolButton> #i…

加密与CA证书

文章目录 加密与CA证书http协议是不安全的使用对称秘钥进行数据加密非对称秘钥加密CA证书应用补充 加密与CA证书 CA 证书是什么&#xff0c;证书的目的是什么 首先明确一点&#xff0c;CA证书是数字时代中确保身份和数据安全的重要工具&#xff0c;为用户提供了安心、便捷和可…

齿轮端面倒棱刀具设计及模拟,记录一下

最近&#xff0c;我深陷在一项复杂且繁琐的任务中&#xff0c;几乎快要被其折磨得近乎疯狂。然而&#xff0c;经过一番努力&#xff0c;我终于迎来了曙光&#xff0c;成功完成了齿轮端面倒棱刀具加工的计算模拟。 这项任务&#xff0c;犹如一场旷日持久的战斗&#xff0c;每一…

小程序获取手机号,用户昵称,头像

一、手机号 在微信小程序中&#xff0c;获取用户手机号也需要用户的明确授权。你可以使用 button 组件的 open-type 属性设置为 getPhoneNumber 来实现这个功能。当用户点击这个按钮时&#xff0c;会弹出一个对话框请求用户的授权。如果用户同意&#xff0c;你可以在 bindgetp…

03.Linux文件操作

1.操作系统与Linux io框架 1.1 io与操作系统 1.1.1 io概念 io 描述的是硬件设备之间的数据交互&#xff0c;分为输⼊ (input) 与输出 (output)。 输⼊&#xff1a;应⽤程序从其他设备获取数据 (read) 暂存到内存设备中&#xff1b;输出&#xff1a;应⽤程序将内存暂存的数据…

数据链路层(详细版)【02】

接 数据链路层&#xff08;详细版&#xff09;【01】 文章目录 四、以太网MAC层&#xff08;一&#xff09;MAC地址组成&#xff08;1&#xff09;48位MAC地址格式&#xff08;2&#xff09;单播地址 & 多播地址 & 广播地址&#xff08;3&#xff09;全球管理 & 本…

如何优雅简单地写 Controller 层代码?

本篇就来介绍一下&#xff0c;如何写好一个 controller &#xff0c;让你的接口变的更加优雅&#xff01; 一个完整的后端请求由 4 部分组成&#xff1a; 接口地址&#xff08;也就是 URL 地址&#xff09; 请求方式&#xff08;一般就是 get、set&#xff0c;当然还有 put、…

HDFS HA 修改nameservice

本例中修改将原来的hdfs-ha 修改为 hdfs-ns 停止HDFS, 防止新的业务操作 等待停止结束 KDE中需要调整的配置项如下图所示 a.搜索栏找到fs.defaultFS&#xff0c;将hdfs://hdfs-ha改为hdfs://hdfs-ns b.搜索栏找到dfs.nameservices&#xff0c;将hdfs-ha改为hdfs-ns c.搜索栏找…

DE2-115开发板基于verilog和nioⅡ的流水灯实现

目录 一、 内容概要二、 实现2.1 基于Nios II软核的流水灯2.1.1 准备工作2.1.2 工程搭建2.1.3 硬件代码设计Ⅰ 连接IP核Ⅱ 编写代码Ⅲ 各种配置 2.1.4 软件代码设计Ⅰ 环境构建Ⅱ 编写代码 2.1.5 代码下载Ⅰ 硬件下载Ⅱ 软件下载 2.1.6 运行结果 2.2 Verilog流水灯 三、 心得体…

5.10.4 Vision Transformer的条件位置编码(CPE)

用于视觉 Transformer 的条件位置编码&#xff08;CPE&#xff09;方案与之前预定义且独立于输入标记的固定或可学习位置编码不同&#xff0c;CPE 是动态生成的&#xff0c;并以输入标记的局部邻域为条件。 CPE 可以轻松泛化到比模型在训练期间见过的输入序列更长的输入序列。…