Java第二周学习
- 2020 年 3 月 18 日
- 筆記
Java第二周学习
1. 数组
1.1 定义数组格式
数据类型[] 数组名 = new 数据类型[容量];
int[] arr = new int[10];
赋值左侧
数据类型: 告知编译器,当前数组中能够保存的数据类型到底是什么?并且在确定数据类型之后,整个数组中保存的数据类型无法修改!!! []:
- 告知编译器这里定义的是一个数组类型数据。
- 明确告知编译器,数组名是一个【引用数据类型】
数组名:
- 操作数据非常重要的数据!!!
- 数组名是一个【引用数据类型】
小拓展: int(*) (void *, void *)
赋值号右侧:
new: 申请【XX】内存空间,并且清空整个内存空间中所有二进制位,所有的二进制 位都是0 数据类型: 前后呼应,告知编译器这里支持存储的数据类型到底是什么? [容量]: 容量==> Capacity 告知编译器,当前数组中能够存放的对应数据类型的数据,最大存储多少 个!! 【注意】 一旦确定容量,针对于当前数组,后期容量无法修改
1.2 数组的下标【重点】
规定 数组中的下标是从0开始,到数组的容量 – 1
例如: 数组容量为10 有效下标范围: 0 ~ 9 超出有效下标范围,都是无效下标,后期考虑数组处理异常问题,负数使用问题
操作会出现的问题: 1. 数组下标越界 ArrayIndexOutOfBoundsException
1.3 数组内存分析图
【补充知识点 引用数据类型】 开发中引用数据类型 用于保存其他内存空间的首地址,保存地址之后,CPU可以通过对应的引用数据类型,得到对应的地址,从而访问地址对应内存空间。 引用数据类型包括字符串,数组,对象。就这三个!
获取数组容量的方式 数组名.length 属性 当前数组的属性length是要占用一定的数组空间的,属于数组中的内容,这就是为什么数组中占用的空间要比存储数据计算空间略大一些。
1.4 数组地址转移问题
class Demo3 { public static void main(String[] args) { int[] arr1 = new int[10]; int[] arr2 = new int[10]; arr1[5] = 100; arr2[5] = 500; System.out.println(arr1[5]); System.out.println(arr2[5]); arr1 = arr2; arr1[5] = 2000; System.out.println(arr1[5]); System.out.println(arr2[5]); } }
数组地址转移示意图
1.5 数组在方法中的使用
class Demo4 { public static void main(String[] args) { int[] array = new int[10]; // 调用赋值数组中元素的方法 // 调用参数是一个数组类型的方法,需要传入的内容是数组名 assignIntArray(array); printIntArray(array); } /* 需求: 赋值一个int类型的数组 方法分析: public static 固定格式 不要问 返回值类型: void 无返回值 方法名: assignIntArray 见名知意,动宾结构,小驼峰命名法 形式参数列表: 这里需要的是一个int类型的数组 (int[] arr) 方法声明: public static void assignIntArray(int[] arr) */ /** * 赋值一个指定的int类型数组 * * @param arr 这里需要的参数是一个int类型数组 */ public static void assignIntArray(int[] arr) { for (int i = 0; i < arr.length; i++) { arr[i] = i + 1; } } /* 需求 展示一个int类型数组中保存的数据 方法分析: public static: 不要问 返回值类型: void 方法名: printIntArray 形式参数列表: 这里需要展示的是一个int类型数组 (int[] arr) 方法声明: public static void printIntArray(int[] arr) */ /** * 展示一个int类型数组中保存的数据 * * @param arr 这里需要的是一个int类型数组 */ public static void printIntArray(int[] arr) { for (int i = 0; i < arr.length; i++) { System.out.println("array[" + i + "]=" + arr[i]); } } }
1.6 数组算法
1.6.1 完成一个数组逆序过程
/* 静态数组 int[] arr = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10}; 逆序完成 {10, 8, 6, 4, 2, 9, 7, 5, 3, 1}; 方法的分析 public static 不要问 返回值类型: void 不需要返回值 方法名: 逆序 reverse 形式参数列表: int[] arr 方法声明: public static void reverse(int[] arr) */ /** * 完成对于int类型数组的逆序过程 * * @param arr int类型数组 */ public static void reverse(int[] arr) { int temp = 0; for (int i = 0; i < arr.length / 2; i++) { /* arr[0] = arr[9] arr[1] = arr[8] arr[2] = arr[7] arr[3] = arr[6] arr[4] = arr[5] */ temp = arr[i]; arr[i] = arr[arr.length - 1 - i]; arr[arr.length - 1 - i] = temp; } }
1.6.2 找出数组中最大值所在下标位置
class ArrayMethod2 { public static void main(String[] args) { int[] arr = {1, 3, 5, 7, 19, 2, 4, 19, 8, 10}; int index = maxIndexOf(arr); System.out.println("index:" + index); } /* 需求 从int类型数组中找出对应的最大值下标位置 方法分析: public static 不要问 返回值类型: 数组的下标数据类型是int类型 int 方法名: maxIndexOf 形式参数列表: (int[] arr) 方法声明: public static int maxIndexOf(int[] arr) */ /** * 返回指定int类型数组中最大值的下标位置 * * @param arr int类型数组 * @return 返回值是最大值所在的下标位置 */ public static int maxIndexOf(int[] arr) { // 假定下标为0的元素是数组中最大值。 int maxIndex = 0; // 因为循环过程中,没有必要假定的下标为0的元素和自己比较 // 循环变量从1开始 for (int i = 1; i < arr.length; i++) { /* 如果发现maxIndex保存的下标对应元素,是小于i的 保存对应的i值 */ if (arr[maxIndex] < arr[i]) { maxIndex = i; } } return maxIndex; } }
1.6.3 找出数组中指定元素所在的第一次出现下标位置
class ArrayMethod3 { public static void main(String[] args) { int[] arr = {1, 3, 5, 7, 9, 1, 3, 5, 7, 9}; int index = indexOf(arr, 1); if (index >= 0) { System.out.println("index : " + index); } else { System.out.println("Not Found!"); } } /* 需求: 找出数组中指定元素出现的第一次下标位置 1. 第一次出现的问题 2. 多个元素问题 3. 有可能不存在指定元素。 方法分析: public static 不要问 返回值类型: int 因为需要返回下标 考虑在int范围以内,使用一个明确和正确数据有对立 关系的数据作为【错误标记】 找到对应数据 0 ~ array.length -1 -1 是一个明确的非法下标 方法名: indexOf 找出对应元素所在下标位置 形式参数列表: 首先是一个int类型数组 查询的数据也是int类型 (int[] arr, int find) 方法声明: public static int indexOf(int[] arr, int find) */ /** * 找出指定数组中,指定元素的下标位置,通过返回值返回 * * @param arr 指定的int类型源数据数组 * @param find 指定需要查询的数据 * @return 返回值大于等于0,表示找到对应的数据,否则返回-1 */ public static int indexOf(int[] arr, int find) { // 首先假设对应查询的数据是不存在的!!! int index = -1; // 利用循环,从下标为0的元素开始到最大下标,比对是否存在find for (int i = 0; i < arr.length; i++) { // 发现指定find元素和下标为i的元素一致 if (find == arr[i]) { // 使用index保留对应的下标i index = i; // 终止循环!!! break; } } return index; } }
1.6.4 获取数组中指定下标的元素
class ArrayMethod4 { public static void main(String[] args) { int[] arr = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10}; System.out.println(get(arr, 20)); } /* 需求 找出指定下标的元素 方法分析: public static 不要问 返回值类型: 数组为int类型,这里返回值也是int类型 方法名: get 形式参数列表 指定的数组 int[] arr 指定的下标 int index 0 ~ arr.length - 1 方法声明: public static int get(int[] arr, int index) */ /** * 找出数组中指定下标的元素 * * @param arr 指定的int类型数组 * @param int 指定查询的下标位置 * @return 返回对应下标位置的元素 */ public static int get(int[] arr, int index) { // 用户指定的index不能超出有效下标范围 if (index < 0 || index > arr.length - 1) { /* 返回任何的数据类型都不合适,可以考虑终止方法, 并且告知用户错误是什么 后期课程中可以使用到异常处理 【用户输入参数合法性判断】 */ System.out.println("Input Parameter is Invalid!"); // 当前方法退出!!! System.exit(0); } return arr[index]; } }
1.6.5 找出数组中最小值的下标位置
public class Demo1 { public static void main(String[] args) { int[] arr = {1, 3, 5, 7, 9, 0, 4, 6, 8, 10}; // Ctrl + 1 Assign statement to new local variable int min = minIndexOf(arr); System.out.println("min index : " + min); } /* * 1.1 找出数组中最小值的下标位置 * * 方法分析: * public static 不要问 * 返回值类型: * 这里需要返回数据是数组的下标 * int类型 * 方法名: * minIndexOf * 形式参数列表: * 这里需要一个int类型数组 * (int[] arr) * 方法声明: * public static int minIndexOf(int[] arr) */ /** * 当前方法是找出指定int类型数组中最小值所在的下标位置 * * @param arr int类型数组 * @return 最小值所在的下标位置 */ public static int minIndexOf(int[] arr) { // 假设最小值下标位置是下标为0的元素 int min = 0; for (int i = 1; i < arr.length; i++) { if (arr[min] > arr[i]) { min = i; } } return min; } }
1.6.6 找出数组中指定元素的最后一次出现的下标位置
public class Demo2 { public static void main(String[] args) { int[] arr = {1, 3, 5, 7, 9, 1, 3, 5, 7, 9}; int index = lastIndexOf(arr, 7); System.out.println("last Index Of : " + index); } /* * 1.2 找出数组中指定元素的最后一次出现的下标位置 * 方法分析: * public static 不要问 * 返回值类型: * int 返回值是一个下标 * 方法名: * indexOf 第一次出现的位置 * lastIndexOf 最后一次出现的位置 * 形式参数列表: * 1. 源数据数组,int类型 * 2. 查询的指定元素 int类型 * (int[] arr, int find) * 方法声明: * public static int lastIndexOf(int[] arr, int find) */ /** * 找出数组中指定元素最后一次出现的位置 * * @param arr 指定的int类型源数据数组 * @param find 指定需要查询的数据 * @return 返回值大于等于0表示找到数据,否则返回-1 */ public static int lastIndexOf(int[] arr, int find) { // 假设我们找不到对应的数据 int index = -1; for (int i = arr.length - 1; i >= 0; i--) { // 找到对应元素,保存index,终止循环 if (find == arr[i]) { index = i; break; } } return index; } }
1.6.7 找出指定元素在指定数组中所有下标位置 【难点】
/* 要求: a. 不允许在方法内打印展示 b. 考虑多个数据情况 c. 需要在方法外获取到下标数据信息 d. 不允许使用数组作为返回值 【重点】 1. 尾插法思想,计数器同时也是下一次存放数据的位置 2. 数组作为方法参数之后,是可以近似数据传导 */ /** * 【重点】 * * @author Anonymous */ public class Demo3 { public static void main(String[] args) { int[] arr = {5, 3, 5, 7, 5, 1, 3, 5, 7, 9}; int[] indexArr = new int[arr.length]; int count = allIndexOf(arr, indexArr, 5); // count是查询到的指定元素个数,同时可以利用与循环中,找到对应的元素 for (int i = 0; i < count; i++) { System.out.println(indexArr[i]); } } /* * 1.3. 找出指定元素在指定数组中所有下标位置 【难点】 * 要求: * a. 不允许在方法内打印展示 * b. 考虑多个数据情况 * c. 需要在方法外获取到下标数据信息 * d. 不允许使用数组作为返回值 * 方法分析: * public static 不要问 * 返回值类型: * int 返回找到的指定元素个数 * void 不行!!!少用黑盒方法!!! * boolean true false 局限性比较大 * 方法名: * allIndexOf tips:感谢雄飞同学的友情提示 * 找出所有指定元素的下标位置 * 形式参数列表: * 1. 查询数据的源数据数组 int[] arr * 2. 指定查询的元素 int find * 3. 和源数据数组容量一致的int类型数组,保存对应的下标位置 * (int[] arr, int[] indexArr, int find) * 问题: * 1. 查询数据可能是多个!!! * 2. 数组不能作为返回值!!! * 3. 不允许打印!!! * 4. 外部获取!!! * 思考: * 1. 保存查询数据的下标位置一定会使用到数组 * 2. 保存下标的数组数据类型是int类型 * 解决方案: * 通过方法为参数形式传入一个数组,int类型,保存找到的下标位置 * 思考: * 保存下标的数组容量如果考虑 * 解决方案: * 哪怕源数据数组中所有数据都是指定的元素,最大容量也就是 * 和源数据数组的容量一致【判断的地方!!!】 * * 问题: * 有没有可能性下标为0的元素就是目标元素??? * 0是有效下标范围 * * new创建一个新的数组,int类型数组中,所有的元素初始值都是0 * 任何判断0是有效下标还是无效数据??? * 需求: * 这里需要一个数据,告知我找到数据到底有多少个 * 返回值: * 找到的指定元素的个数,如果没有找到,返回0 * * 方法声明: * public static int allIndexOf(int[] arr, int[] indexArr, int find) * */ /** * 找到指定源数据数组中所有指定元素所在的下标位置,保存到indexArr中,并且返回值 * 是找到的元素个数 * * @param arr 源数据数组,int类型 * @param indexArr 找到的下标位置存储数组,要求该数组的容量不得小于源数据容量 * @param find 需要查询的指定数据 * @return 返回值大于0,找到的数据个数,没有找到返回0 */ public static int allIndexOf(int[] arr, int[] indexArr, int find) { // 参数合法性判断 // 如果存储下标的数组长度小于原数组长度,有可能存储不完数据, // 这里就要提醒用户给的数组长度不对 if (arr.length > indexArr.length) { System.out.println("Input Parameter is Invalid!"); // 参数不合法,没有找到数据 return 0; } /* * 定义一个变量, * 1. 计数器,记录找到的元素个数 * 2. 尾插法当中下一次存放元素的位置 */ int count = 0; // 利用for循环遍历整个源数据arr数组 for (int i = 0; i < arr.length; i++) { // 找到了对应的元素,需要保存下标i if (find == arr[i]) { // 保存到indexArr数组中 // 需要使用尾插法!!!保存下一次存放数据的位置 indexArr[count] = i; // 计数器 += 1 count += 1; } } return count; } }
1.6.8 在指定位置插入指定元素【难点】
/* 存在一个数组,数组中的元素为 int[] array = {1, 3, 5, 7, 9, 11, 13, 15, 17, 0}; 要求 1. 0是无效元素,仅占位使用 2. 当前数组中【有效元素】个数为9 需求 在该数组中的指定下标位置放入指定元素 【重点】 1. 空数据,无效数据思想 2. 数据的移动过程,粗加工,细打磨过程 3. 时间消耗问题 */
public class Demo4 { public static void main(String[] args) { int[] array = {1, 3, 5, 7, 9, 11, 13, 15, 17, 0}; add(array, 9, 20); System.out.println(Arrays.toString(array)); } /* 1.4 在指定位置插入指定元素【难点】 存在一个数组,数组中的元素为 int[] array = {1, 3, 5, 7, 9, 11, 13, 15, 17, 0}; 要求 1. 0是无效元素,仅占位使用 ==> null 2. 当前数组中【有效元素】个数为9 需求 在该数组中的指定下标位置放入指定元素 推演过程: 在数组下标为5的位置插入元素,从下标5开始 之后的元素整体向右移动 arr[9] = arr[8]; arr[8] = arr[7]; arr[7] = arr[6]; arr[6] = arr[5]; arr[5] = 20; 指定下标为5的位置添加元素,数组中的元素整体 向后移动的4次 方法分析: public static 不要问 返回值类型: void 可用,但是不建议 boolean 可以 true false 选择boolean类型 int 可用 返回值的含义约束较为麻烦 方法名: add 添加操作 形式参数列表: 1. 需要插入数据的数组 2. 指定插入数据的下标位置 3. 指定插入的数据 (int[] arr, int index, int insert); 方法声明: public static boolean add(int[] arr, int index, int insert); */ /** * 在指定的数组中,指定位置插入指定元素 * * @param arr 指定的int类型数组 * @param index 指定的下标位置,必须在合理的区间范围以内 * @param insert 指定插入的元素,int类型 * @return 添加成功返回true,否则返回false */ public static boolean add(int[] arr, int index, int insert) { // 参数合法性判断 if (index < 0 || index > arr.length - 1) { System.out.println("Input Parameter is Invalid!"); // 方法运行失败!!! return false; } /* arr[9] = arr[8]; arr[8] = arr[7]; arr[7] = arr[6]; arr[6] = arr[5]; arr[i] = arr[i - 1]; arr[i + 1] = arr[i]; arr[5] = 20; */ for (int i = arr.length - 1; i > index; i--) { arr[i] = arr[i - 1]; } arr[index] = insert; return true; } }
1.6.9 删除数组中的指定下标的元素【难点】
/* 存在一个数组,数组中的元素为 int[] array = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19}; 要求: 1. 0是无效元素,仅占位使用 需求: 在当前数组中删除指定下标的元素 例如: 指定下标5 结果 {1, 3, 5, 7, 9, 13, 15, 17, 19, 0} 0占位!!! */
package com.qfedu.a_array; import java.util.Arrays; public class Demo5 { public static void main(String[] args) { int[] array = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19}; remove(array, 9); System.out.println(Arrays.toString(array)); } /* 1.5 删除数组中的指定下标的元素【难点】 存在一个数组,数组中的元素为 int[] array = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19}; 要求: 1. 0是无效元素,仅占位使用 需求: 在当前数组中删除指定下标的元素 例如: 指定下标5 结果 {1, 3, 5, 7, 9, 13, 15, 17, 19, 0} 0占位!!! 推理过程: 从删除位置开始,之后的元素整体向前移动, 并且需要在数组原本最后一个位置上存放元素0,0 是无效元素,占位使用 arr[3] = arr[4]; arr[4] = arr[5]; arr[5] = arr[6]; arr[6] = arr[7]; arr[7] = arr[8]; arr[8] = arr[9]; arr[i] = arr[i + 1]; arr[i - 1] = arr[i]; arr[9] = 0; 方法分析: public static 不要问 返回值类型: boolean 方法名: remove 形式参数列表: 1. 删除数据的数组 2. 指定删除数据的下标位置 方法声明: public static boolean remove(int[] arr, int index) */ /** * 删除数组中指定下标元素的内容 * * @param arr 源数据数组,int类类型 * @param index 指定删除的下标位置 * @return 删除操作成功返回true,失败返回false */ public static boolean remove(int[] arr, int index) { // 参数合法性判断 // index < 0 || index >= arr.length if (index < 0 || index > arr.length - 1) { System.out.println("Input Parameter is Invalid"); return false; } /* arr[3] = arr[4]; arr[4] = arr[5]; arr[5] = arr[6]; arr[6] = arr[7]; arr[7] = arr[8]; arr[8] = arr[9]; arr[i] = arr[i + 1]; 从删除位置开始,到数组的最后一个有效元素位置结束 */ for (int i = index; i < arr.length - 1; i++) { arr[i] = arr[i + 1]; } // 最后一位数据赋值为0,占位,同时告知用户这是一个无效数据 arr[arr.length - 1] = 0; return true; } }
1.6.10 找出数组中最大值元素,放到下标为0的位置
// 找出数组中最大的元素,放到下标为0的位置,下标为0的元素放到最大值元素位置 int[] arr = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 10 }; System.out.println(Arrays.toString(arr)); // 假设最大值的下标位置为0 int index = 0; // 这里一定可以得到最大值所在的下标位置 for (int i = 1; i < arr.length; i++) { if (arr[index] < arr[i]) { index = i; } } // 交换数据 if (index != 0) { int temp = arr[0]; arr[0] = arr[index]; arr[index] = temp; } System.out.println(Arrays.toString(arr));
1.6.11 接上一题,找出数组中剩余元素的最大值,放到下标为1的位置
int index1 = 1; for (int i = 2; i < arr.length; i++) { if (arr[index1] < arr[i]) { index1 = i; } } if (index1 != 1) { int temp = arr[1]; arr[1] = arr[index1]; arr[index1] = temp; } System.out.println(Arrays.toString(arr));
1.6.12 再接上一题,找出数组中剩余元素的最大值,放到下标为2的位置
int index2 = 2; for (int i = 3; i < arr.length; i++) { if (arr[index2] < arr[i]) { index2 = i; } } if (index2 != 2) { int temp = arr[2]; arr[2] = arr[index2]; arr[index2] = temp; } System.out.println(Arrays.toString(arr));
1.6.13 选择排序算法
public class Demo7 { public static void main(String[] args) { int[] arr = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 10 }; System.out.println(Arrays.toString(arr)); selectSort(arr); System.out.println(Arrays.toString(arr)); } /* * 选择排序算法 * 方法分析: * public static 不要问 * 返回值类型: * void * 方法名: * selectSort * 形式参数列表: * 需要处理一个int类型数据 * (int[] arr) * * 方法声明: * public static void selectSort(int[] arr) */ /** * 选择排序算法 * * @param arr 需要进行排序的int类型数据 */ public static void selectSort(int[] arr) { // 外层循环控制核心算法的循环次数 for (int i = 0; i < arr.length - 1; i++) { // 从index位置开始找寻极值 int index = i; for (int j = i + 1; j < arr.length; j++) { if (arr[index] > arr[j]) { index = j; } } if (index != i) { int temp = arr[i]; arr[i] = arr[index]; arr[index] = temp; } } } }
1.7 Arrays数组工具类使用
数组的工具类: 提供了数组操作的基本方法 sort(int[] arr); 经过XXX,XXX,XXX三个大牛优化的利用XXX技术完成的快速排序算法
binarySearch(int[] arr, int find); 二分法查询,要求数组是有序的。
toString(任何类型数组); 把数组内容作出一个String类型字符串返回值 {1, 3, 5, 7, 9} ==> [1, 3, 5, 7, 9]
2. Eclipse使用
2.1 Eclipse使用
- 解压缩Eclipse.rar
- 发送快捷方式到桌面
- 选择自定义Workspace
- Eclipse开发环境选择
- 创建Java Project a. 菜单栏 –> New – > Java Project b. Package Explorer –> 鼠标右键 –> New – > Java Project
- 怎么修改工作目录默认保存的位置
3. 面向对象
3.1 Java中定义类的格式
class ClassName { // 属性描述 // 行为描述 }
要求: 1. ClassName要求符合大驼峰命名法,并且要做到见名知意!!! 2. 属性描述,是用于描述当前类拥有的一些特征,这里可以使用变量 该变量有一个特定的名字【成员变量】 Field 3. 行为描述,是用于描述当前类可以做到一些事情,这里使用方法。 该方法有一个特定的名字【成员方法】Method
3.2 Java中定义类【成员变量】
/** * 这里定义的是一个Person类 * * @author Anonymous */ class Person { // 属性描述,这里使用成员变量 Field // 使用String类型来描述Person类的姓名属性 String name; // 使用int类型数据描述Person类的年龄属性 int age; // 使用char类型数据描述Person类的性别属性 char gender; }
3.3 Java中定义类【成员方法】
// 使用方法描述Perosn类的吃饭行为 public void eat(String food) { System.out.println("吃" + food); } // 使用方法描述Person类的睡觉行为 public void sleep() { System.out.println("说出来你可能不行,是床先动的手~~~"); } // 使用方法描述Person类的打豆豆行为 public void daDouDou() { System.out.println("吃饭,睡觉,打豆豆"); } /* 特征: 1. 目前没有使用static关键字 2. 方法和之前所学方式形式一致,同样拥有三大元素 返回值,方法名和形式参数列表 */
3.4 类对象使用
3.4.1 Java中创建类对象的形式
/* new 对象!!! */ // 获取一个扫描器的类对象!!! Scanner sc = new Scanner(System.in); /* java.util.Scanner : 数据类型,Scanner类型。创建的【变量】是Scanner的类对象,同时也是一个引用 数据类型 sc : 类对象,变量 Scanner的类对象,sc是对象名 new : 申请内存的【堆区】空间,并且清理整个空间中的所有数据。 代码中,只有有new关键字,一定会使用到内存的堆区空间,并且是新的内存空间。 Scanner(System.in) : 1. 这里是一个方法,因为有小括号 2. 方法名字和类名一致 3. 该方法称之为构造方法,Constructor 构造方法 总结: 类名 对象名 = new 构造方法(所需参数); */ // 这里创建了一个Person类对象,对象名person Person person = new Person(); System.out.println(person); /* * com.qfedu.a_object.Person@15db9742 * com.qfedu.a_object 完整的包名 * Person 数据类型,这里创建的对象是一个Person类对象 * @15db9742 当前类对象在内存空间的中首地址!!!十六进制展示方式 */ Person person1 = new Person(); System.out.println(person1); /* * com.qfedu.a_object.Person@6d06d69c * 发现第二个Person类对象 person1空间首地址6d06d69c 和第一个对象不一致 * 这里就意味着两个对象的空间首地址不一致,不是同一个对象!!! */
3.4.2 Java中使用类对象调用成员变量
/* int[] arr = new int[10]; 获取数组的容量: arr.length 获取一个数组中【的】length属性 格式: 对象名.属性名/成员变量名; . ==> 的 可以操作取值或者赋值操作。 */ // 通过Person类对象 person调用类内的成员变量 // 【赋值】Person类对象 person中对应的成员变量 person.name = "骚磊"; person.age = 16; person.gender = '男'; // 【取值】展示Person类对象 person中保存的成员变量数据 System.out.println("Name:" + person.name); System.out.println("Age:" + person.age); System.out.println("Gender:" + person.gender);
3.4.3 Java中使用类对象调用成员方法
/* 得到了一个Scanner类对象sc Scanner sc = new Scanner(System.in); 使用过以下方法: sc.nextInt(); sc.nextFloat(); sc.nextLine().charAt(0); 格式: 类对象.方法名(必要的参数); . ==> 的 */
3.5 类对象内存分析图
3.6 类对象内存转移问题
4. 构造方法 Constructor
4.1 Java编译器提供的默认的构造方法
Java编译器如果发现当前class没有显式自定义构造方法,会默认提供一个无参数构造方法给予使用。 如果Java编译器发现在代码中出现了任何一个构造方法,就不会再提供对应的无参数构造方法。
4.2 自定义使用构造方法
构造方法功能: 初始化当前类对象中保存的成员变量数据。 目前创建对象的方式; new 构造方法(有可能需要的参数);
new: 1. 根据构造方法提供的数据类型申请对应的堆区内存空间。 2. 擦除整个空间中所有的数据。 构造方法: 初始化在当前内存堆区空间的成员变量对应的数据
格式: public 类名(初始化形式参数列表) { 初始化赋值语句; }
要求: 1. 无论什么时候一定要留有一个无参数构造方法备用 2. 根据所需情况完成构造方法参数选择 3. 一个class可以有多个构造方法【方法的重载】
5. 方法的重载
总结: 1. 所有的方法名字都是一致的!!! 2. 所有的方法参数都是不一样的!!! 3. 同一个类内!!!
这就是方法的重载!!! 优点: 1. 简化了开发压力 2. 简化了记忆压力 3. 更快捷的调用方法,同时又满足了不同的情况!!!
规范: 重载情况下,在同一个类内,不可以出现相同方法名和相同参数数据类型的方法!!!
基本原理: 方法名一致的情况下,通过形式参数列表数据类型的不同来选择不同的方法执行。 反射 ==>Constructor Method
6. this关键字
6.1 this关键字特征
class SingleDog { public SingleDog() { System.out.println("Constructor : " + this); } public void test() { System.out.println("Method Called : " + this); } } /* * this关键字特征: * this关键字表示调用当前方法的类对象, * 或者是当前构造方法中初始化的类对象 */ public class Demo4 { public static void main(String[] args) { SingleDog singleDog = new SingleDog(); System.out.println("Instance : " + singleDog); singleDog.test(); } }
6.2 解决就近原则问题
/** * 使用String类型参数和int类型参数初始化类对象成员变量数据 * * @param name String类型数据 用于初始化name属性 * @param age int类型数据 用于初始化age属性 */ public Cat(String name, int age) { name = name; age = age; System.out.println("带有两个参数的构造方法"); } /* 我们期望使用比较直观的参数名方式,告知调用者这里需要的数据到底是什么? 但是会导致【就近原则】问题 在构造方法中所有的name,age都会被看作是一个局部变量,而不是成员变量 期望: 可以有一种参数方式告知编译器这里操作的是一个成员变量,而不是一个局部变量!!! */ --------------------------修改方式---------------------------------- /** * 使用String类型参数和int类型参数初始化类对象成员变量数据 * * @param name String类型数据 用于初始化name属性 * @param age int类型数据 用于初始化age属性 */ public Cat(String name, int age) { /* * 使用this关键字明确告知编译器这里使用的是一个成员变量,而不是 * 局部变量,解决就近原则问题 */ this.name = name; this.age = age; }
成员变量和局部变量的对比
区别 |
成员变量 |
局部变量 |
---|---|---|
作用 |
属性描述,描述当前类拥有哪些属性 |
在方法运行的过程中保存必要的数据 |
位置 |
成员变量定义在class大括号以内,其他大括号之外 |
在方法大括号或者代码块大括号以内 |
初始值 |
成员变量在没有被构造方法赋值的情况下,是对应数据类型的"零"值 |
未赋值不能参与除赋值之外的其他运算。 |
作用域 |
成员变量存储于类对象中,在内存的堆区,哪里持有当前类对象的空间首地址,作用域就在哪里 |
有且只在当前大括号以内 |
生存期 |
成员变量的生存期是随着类对象的创建而开始,当对象被JVM的GC销毁时,成员变量的生存期终止 |
从定义位置开始,到当前大括号结束 |
7. 【补充知识点 "零"值】
new关键字申请内存空间,并且擦除的一干二净 对应每一个数据类型的"零"值 基本数据类型 byte short int 0 long 0L float 0.0F double 0.0 char ‘