- 方法区:加载的类的模板结构。
类的内存解析:
- **堆:**存放new出来的对象,对象中存放的是对象的成员变量(起初是默认值)。没有new,就不会新开辟空间。
- **栈:**存放的是对象名,代表的是对象的首地址。调用成员变量时,会给对中的成员变量赋值。
- **方法区:**用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的
代码等数据。
成员变量 VS 局部变量:
- **成员变量:1、**类内-方法体外声明的变量。2、随对象的创建,存储在堆空间。3、随着对象的创建而创建,随着对象的消亡而消亡。4、能用权限修饰符修饰。5、有默认值,所以不用必须显式赋值。
- 局部变量:1、方法体内等位置声明的变量。2、存储在栈空间。3、随着方法对应的栈针入栈,局部变量在栈中分配,随着方法对应的栈针出栈,局部变量消亡。4、不能用任何权限修饰符进行修饰。5、在使用局部变量前,必须显式赋值。
例如,员工的生日属性。首先,需要先创建Mydate类,包含了生日的年、月、日属性。
接着,在另一个类中声明birthday时,可以直接使用Mydate类作为生日的数据类型。
接着,创建对象,调用属性。
二、方法
方法的声明
- public void eat();
- public void sleep(int hour);
- public String interests(String hobby); //调用该方法时要传入形参,并有一个变量接收返回值
- public int age(); //调用该方法时,要有一个变量接收返回值。
在声明方法时,要不要提供返回值类型(要不要有返回值)以及要不要传形参,则具体问题具体分析。
方法注意事项
- 必须先声明后使用,且方法必须定义在类的内部
- 调用一次就执行一次,不调用不执行。
- 方法中可以调用类中的方法或属性,不可以在方法内部定义方法。
return关键字的作用
- 作用
1
:结束一个方法。 - 作用2
:结束一个方法的同时,可以返回数据给方法的调用者。 - return后面不能再声明执行语句。
Q:如果main和方法在同一个类中,在main中不声明对象调用方法的情况下,方法要用static修饰???(后面待解决)
例如,
这样的话,方法会报错。当方法声明时加上static后,可以不用创建对象调用。例如:
方法调用的内存解析
每一个方法对应一个栈针。
- 方法 没有被调用 的时候,都在 方法区 中的字节码文件(.class)中存储。
- 方法 被调用 的时候,需要进入到 栈内存 中运行。方法每调用一次就会在栈中有一个 入栈 动作,即
- 给当前方法开辟一块独立的内存区域,用于存储当前方法的局部变量的值。
- 当方法执行结束后,会释放该内存,称为 出栈 ,如果方法有返回值,就会把结果返回调用处(例如在main方法中调用某个方法,该方法的返回值是返回到main中),如果没有返回值,就直接结束,回到调用处继续执行下一条指令。
- 栈结构:先进后出,后进先出。
三、对象数组
数组的元素可以是基本数据类型,也可以是引用数据类型。当
元素是引用类型中的类
时,我们称为对象数组。
例如,我们要查看20个学生对象的基本信息,其中,每个学生对象都包含多个属性,“学生”就可作为一个类作为引用数据类型。20个学生组成对象数组,其中每个元素即每个学生的数据类型是“学生”。
**格式举例:**Student[ ] students=new Student[20];
当我们需要为每个学生对象的属性赋值等操作时,需要再次创建对象。即students[i]=new Student()。
案例一:
定义类Student,包含三个属性:学号number(int),年级state(int),成绩score(int)。 创建20个学生对象, * 学号为1到20,年级和成绩都由随机数确定。 * 问题一:打印出3年级(state值为3)的学生信息。 * 问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息
public class student_Test {
public static void main(String[] args) {
Student[] students=new Student[20];//创建对象数组。
for(int i=0;i<students.length;i++){
students[i]=new Student();//要为20个学生依次new对象,堆中
students[i].number=i+1;
students[i].state=(int)(Math.random()*6+1);//[1,6]
students[i].score=(int)(Math.random()*101);//[0,100]
}
int state=3;
for(int i=0;i<students.length;i++){
if(state==students[i].state){
System.out.println(students[i].printStudents());
}
}
//局部变量存放在栈中。属性(成员变量)在堆中
for(int i=0;i<students.length-1;i++){
boolean flag=true;//元素已经是排好序的
for(int j=0;j<students.length-1-i;j++){
if(students[j].score>students[j+1].score){
Student temp=students[j];//这里使用students[j].score是错误的,因为我们要把学生的所用属性进行一个交换。
students[j]=students[j+1];
students[j+1]=temp;
flag=false;//设为false,证明元素在该轮交换了一次
}
}
if(flag){ //如果为true,则表明在i轮后,并未再次进行交换,元素已经有序,此时可以跳出循环了
break;
}
}
System.out.println();
for(int i=0;i<students.length;i++){
System.out.println(students[i].printStudents());
}
}
}
案例二:
(
1
)定义矩形类
Rectangle
,包含长、宽属性,
area()
返回矩形面积的方法,
perimeter()
返回矩形周长的方法,
String getInfo()
返回圆对象的详细信息(如:长、宽、面积、周长等数据)的方法(
2
)在测试类中创建长度为
3
的
Rectangle[]
数组,用来装
3
个矩形对象,并给
3
个矩形对象的长分别赋值为
10,20,30
,宽分别赋值为
5,15,25
,遍历输出
案例二 内存解析:
area()方法和perimeter()方法调用都将返回值返回到getInfo()中, 然后依次出栈。
四、方法的重载
定义
在同一个类中,允许存在一个以上的同名方法,只要它们的参数列表不同即可。【参数列表不同,意味着参数个数或参数类型的不同 ,和形参名、修饰符、返回值类型都没有关系。】
Q:编译器是如何确定调用的是某个具体的方法呢?
答:编译器先通过方法名确定一波重载的方法,再根据形参列表确定具体的某一方法。
注意:下图中,打印出的值为什么中间这个是具体的值,其它是地址值?
因为println是有一系列重载的方法,如下图,其中这个数组arr1和arr2(引用类型了)就对应Object。Object类型默认是打印地址值。
五、可变个数的形参
格式: 方法名(参数类型… 参数名)
- 可变个数形参的方法在调用时,可赋的实参个数可以是0个、1个或多个。
- 可变个数形参的方法与同名的方法之间,彼此构成重载 。
- 可变参数方法的使用与方法参数部分使用数组是一致的,二者不能同时声明,否则报错。
- 方法的参数部分有可变形参,需要放在形参声明的最后.
- 在一个方法的形参中,最多只能声明一个可变个数的形参.
场景举例:
六、方法的值传递机制(重要)
1、(复习)对于方法内声明的局部变量来说:
如果出现赋值操作,
- 如果是基本数据类型的局部变量,则把数据值传递过去。
- 如果是引用数据类型(有数组或对象)的局部变量,则把其地址值传递过去。
2、方法的参数传递机制
- 如果形参是基本数据类型的变量,则将实参保存的数据值传递给形参。
- 如果形参是引用数据类型的变量,则将实参保存的地址值传递给形参。
3、内存解析:
Java面试题: JAVA中的参数(变量)传递机制是什么?答:值传递。看传的是什么值了。(不是引用传递。)
答案:
//方法一:
public void method(int a,int b){
a=a*10;
b=b*20;
System.out.println("a="+a);
System.out.println("b="+b);
System.exit(0);//正常终止当前运行的Java虚拟机,main函数后面的代码则不会再运行了。
}
//方法二:暂时先不理解了,等后续再看!!
public static void method(int a, int b) {
PrintStream ps = new PrintStream(System.out) {
@Override
public void println(String x) {
if ("a=10".equals(x)) {
x = "a=100";
} else if ("b=10".equals(x)) {
x = "b=200";
}
super.println(x);
}
};
System.setOut(ps);
}
七、方法的递归
举例:
注意:
1. 递归调用会占用大量的系统堆栈,内存耗用多,在递归调用层次多时速度要比循环 慢的
多 ,所以在使用递归时要慎重。
2. 在要求高性能的情况下尽量避免使用递归,递归调用既花时间又 耗内存 。考虑使用循环迭
代。
八、面向对象的特征一:封装性
内聚,指一个模块内各个元素彼此结合的紧密程度;耦合指一个软件结构内不同模块之间互连程度 的度量。内聚意味着重用和独立,耦合意味着多米诺效应牵一发动全身。
1、为什么要封装?
理论上:
- 高内聚:类的内部数据操作细节自己完成,不允许外部干涉;
- 低耦合:仅暴露少量的方法给外部使用,尽量方便外部调用。
通俗来讲,就是把该隐藏的隐藏起来,该暴露的暴露出来。这就是封装性的设计思想。
2、如何实现数据封装?
- 使用4种权限修饰符:public 、 protected 、 缺省 、 private
其覆盖范围如下:(这里的子类估计就是继承那种的子类)
- 具体修饰结构
- 外部类:public、缺省
- 成员变量、成员方法、构造器、成员内部类:public、protected、缺省、private
3、封装作用
可以使用4种权限修饰符修饰类及类的内部成员,当这些成员被调用时,体现其可见性的大小。【问什么是封装性呢?】
4、案例
public class AnimalTest {
**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**
**深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**
**因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
![img](https://img-blog.csdnimg.cn/img_convert/e17f43897798e4ecce9519e32b800904.png)
![img](https://img-blog.csdnimg.cn/img_convert/53aaa6772b81879a04d53a955df1a8ee.png)
![img](https://img-blog.csdnimg.cn/img_convert/ef13295c3442ccc456839597be723d55.png)
![img](https://img-blog.csdnimg.cn/img_convert/4b8cc56380084cec46b464526312f59a.png)
![img](https://img-blog.csdnimg.cn/img_convert/6c361282296f86381401c05e862fe4e9.png)
![img](https://img-blog.csdnimg.cn/img_convert/9f49b566129f47b8a67243c1008edf79.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!**
**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**
**如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注:Python)**
.(img-gWmGvHwx-1713594724853)]
[外链图片转存中...(img-8ufLXjgk-1713594724853)]
[外链图片转存中...(img-Xe0ZLLIx-1713594724854)]
![img](https://img-blog.csdnimg.cn/img_convert/6c361282296f86381401c05e862fe4e9.png)
![img](https://img-blog.csdnimg.cn/img_convert/9f49b566129f47b8a67243c1008edf79.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!**
**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**
**如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注:Python)**
![](https://img-blog.csdnimg.cn/img_convert/5ea1483ada3a9ac91af5fe36a2d80e44.jpeg)