1. 方法
1.1 方法执行时的内存变化:
- 方法只定义不调用是不会分配内存的。只是方法的字节码指令存储在
元空间
中。 - 方法在调用的瞬间,会给该方法分配内存空间,会在栈中发生压栈动作。每个方法都会有自己的空间,这个空间称为
栈帧
- 栈帧中主要包括:局部变量表,操作数栈等。
- 方法执行结束之后,给该方法分配的内存空间全部释放,此时发生弹栈动作。
1.2 overload 方法重载
- 方法重载是
编译阶段
的一种机制(静态多态) - 什么情况下构成方法重载?
- 在同一个类中,且
- 方法名相同,且
- 参数列表不同(类型或顺序或个数不同都算不同)
- 什么时候考虑方法重载?
在同一个类中,如果功能相似,建议使用方法重载。
// 想使用哪个方法,只要传对参数就行,不必强行给两个功能一样的函数起不同名字.// 加两个整数public int add(int a, int b) {return a + b;}// 加两个浮点数public double add(double a, double b) {return a + b;}
1.3 override 重写方法
1.4 值传递和引用传递
- Java 本质上都是“值传递”。基本数据类型就是复制了具体值,引用数据类型就是复制了地址。
值传递
:传递对象的一个副本,即使副本被改变,也不会影响源对象,因为值传递的时候,实际上是将实参的值
复制一份给形参。引用传递
:传递的并不是实际的对象,而是对象的引用,外部对引用对象的改变也会反映到源对象上,因为引用传递的时候,实际上是将实参的地址
值复制一份给形参。- 对象传递(数组、类、接口)是引用传递,原始类型数据(整形、浮点型、字符型、布尔型)传递是值传递。
但有几个需要注意的点:
- String 创建之后是不可变更的。
/* 该程序两次输出都是 OLD STRING
* 首先,String str = new String("OLD STRING") 后,会在字符串常量池创建一个 OLD STRING 实例* 当调用 changeString(str) 时,传递的是 str 引用的副本(实际上是值传递)。
* 即原本有一个指针 str 指向 OLD String,现在复制了一个指针 string 也指向 OLD String
* 在changeString方法内部,你创建了一个新的字符串"NEW STRING",并且让局部变量string(它是str的副本)指向这个新创建的字符串。这一操作完全不会影响到原始的str引用,因为字符串是不可变的,你不能改变str原本指向的对象的内容,只能改变string这个局部变量本身。
* 当我们执行 changeString(str);
* 其实相当于执行了 new String(changeString(str));*/public static void main(String[] args) {String str = new String("OLD STRING");System.out.println(str);changeString(str);System.out.println(str);}public static void changeString(String string) {string = new String("NEW STRING");}
2. 对象
- 对象和引用的区别什么?
对象:new 出来的,实际存储数据的实体。
引用:是一个保存了对象内存地址的变量,可以理解为指针
。
- 第一个角度 :
指针
Person person1 = new Person("Alice", 30);
Person person2 = person1;
new Person(“Alice”, 30) 创建了一个 Person 类型的对象。
person1 是一个引用,它存储了新创建对象在堆内存中的地址。
当执行 person2 = person1 时,person2 变成了第一个对象在堆内存中地址的一个副本。这意味着 person1 和 person2 现在指向同一个 Person 对象。可以看到,引用和指针几乎是同义词。
- 第二个角度:
操作对象的工具
- new 出来的对象,保存在堆内存
- 但在 Java 中,程序员是不能直接操作堆内存,需要借助引用来访问堆内存。
2.1 对象的内存分析
- new 运算符会在 JVM 的堆内存中分配空间用来存储实例变量。new 分配的空间就是 Java 对象。
- 在 JVM 中对象创建后会有对应的内存地址,将内存地址赋值给一个变量,这个变量被称为
引用
。 - JVM 中的 GC 主要针对的是
堆内存
。
2.2 封装
- 在代码上如何实现封装?
把属性私有化,对外提供 getter 和 setter 方法。