Day04 内存划分、递归、数组初识
JavaSE- 重载、递归、内存分析
1.方法重载
特点
1)方法名一定要相同
2)参数列表不同——参数类型、参数个数
3)与方法的访问控制符和返回值无关
示例
1)定义一个无参构造方法
2)定义一个带一个参数构造方法,初始化姓名属性。
3)定义一个带一个参数构造方法,初始化年龄属性。
4)定义一个带两个参数构造方法,初始化姓名、年龄属性。
2.5对象的引用与this
引用
Student s = new Student(“张三”);
上面的对象名s即为对象的引用,而 new Student(“张三”)才是张三对象。
this
总要有个事物来代表类的当前对象,就像C++中的this指针一样,Java中的this关键字就是代表当前对象的引用。
图例
它有三个主要的作用
1)在构造方法中调用其他构造方法
比如:有一个Student类,有三个构造函数,某一个构造函数中调用另外构造函数,就要用到this(),而不可以直接使用Student()。
2)返回当前对象的引用
3)区分成员变量名和参数名
2. static
static关键字的用途
在《Java编程思想》P86页有这样一段话:
“static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。这实际上正是static方法的主要用途。”
这段话可以看出static关键字的基本作用:方便在没有创建对象的情况下来进行调用(方法/变量)。
很显然,被static关键字修饰的方法或者变量不需要依赖于对象来进行访问,只要类被加载了,就可以通过类名去进行访问。
static方法
static方法一般称作静态方法,由于静态方法不依赖于任何对象就可以进行访问,因此对于静态方法来说:
- static是没有this的,因为它不依附于任何对象,既然都没有对象,就谈不上this了。
- 在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。
- 虽然在静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成员方法中是可以访问静态成员方法/变量的。
static变量
static变量也称作静态变量,静态变量和非静态变量的区别是: - 静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。
- 非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。
3.递归方法
3.1释义
程序自身调用自身的编程技巧称为递归
3.2递归四个特性
1.必须有可最终达到的终止条件,否则程序将陷入无穷循环;
2.子问题在规模上比原问题小,或更接近终止条件;
3.子问题可通过再次递归调用求解或因满足终止条件而直接求解;
4.子问题的解应能组合为整个问题的解。
3.3技巧
找到递归实现的递归部分和终止部分
斐波那契数列
Fibonacci: 1 , 1 , 2 , 3 , 5 , 8 , 13 , 21 … …
终止部分:F1=1,F2=1;
递归部分为:F(n)=F(n-1)+F(n-2),其中n>2
图解斐波那契递归过程
public static int fib(int n) throws Exception {
if (n < 0)
throw new Exception(“参数不能为负!”);
else if (n == 0 || n == 1)
return n;
else
return fib(n - 1) + fib(n - 2);
}
- JVM内存分析——案例
JAVA的JVM的内存可分为3个区:堆(heap)、栈(stack)和方法区(method)
堆区:
1.存储的全部是对象,每个对象都包含一个与之对应的class的信息。
2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身。
3.一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。
栈区:
1.每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中。
2.每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
3.栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。
4.由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。
静态区/方法区:
1.方法区又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。
2.方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。
3.全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。
1、 数组基本概念
数组可以看成是多个相同类型数据的组合,实现对这些数据的统一管理
数组中的每一个数据 — 数组的一个元素(element)
数组中的元素可以是任何数据类型,包括基本数据类型和引用类型
数组中元素的个数,称为数组的长度(length)
Java语言中声明数组时不能指定其长度
e.g. int a[5]; //非法
2、一维数组操作
1、一维数组的声明
2、一维数组的创建
3、数组的内存模型
• 数组是存储多个相同类型变量的对象。数组的所有元素保存在堆内存中。
• 创建一个数组就是在堆中创建一个数组对象。
• 数组创建后立即拥有默认值。
• 索引从0开始。
• 连续分配
• 6数组的长度(length)必须>=0;
• length为只读。
• 利用length遍历数组
4、二维数组初始化
int[ ][ ] a = new int[3][ ];
a[0] = new int[2];
a[1] = new int[3];
a[2] = new int[4];
a[0][0] = 1;
a[0][1] = 2;
5、二维数组遍历
int[][] a = {{1, 2}, {3, 4, 5, 6}};
// for
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
System.out.println(a[i][j]);
}
}
// for/each
for (int[] t: a) {
for (int e: t) {
System.out.println(e);
}
}