一、一维数组
1. 变量名指向地址
2. 数组新建和输入
3. 数组可以先声明后分配

这种情况的话实际上是先new了一个指针a,a此时指向null,后面再将a指向new int[3]分配的空间
4. 静态初始化
5. 数组使用的一些注意细节
6. 值传递和引用传递的区别

其实不管是基本数据类型还是引用类型,拷贝的时候都是从栈中直接赋值变量名指向的东西过去,区别就在于n1指向的是数而arr1指向的是地址
7. 数组拷贝

8. 数组的扩容

二、 二维数组
1. 动态初始化
2. 内存存在形式

3. java数组可以列数不确定,列数可以不一样

遍历的时候才真正开空间
4. 静态初始化
5. 二维数组的注意细节
6. 对数组声明和初始化的理解练习
三、面对对象基础篇
1. 内存中对象的存在形式
2. 成员变量的注意细节
ps:基本数据类型和引用类型

基本数据类型就这几种,其他的都是引用类型

注意 p1只是 对象名,new出来的空间才是真正的对象
就比如小明和李明都是这个人的名字而已,并不是他自己
3. 创建对象的方法
先声明对象cat,此时cat指向null,等new cat的时候,在堆中创建空间,然后将该空间的地址比如OX1122赋值给cat,cat就指向了OX1122的这个空间,即指向了这个对象。
4. 类和对象的内存分配机制

执行第一行代码

执行第二行代码

执行第三行代码
(必须注意,有数据就一定有地址空间,将“小明”这个字符串的地址回填)

执行第四行代码(要是前面对老师说的内存分配机制理解够好的话,这里自己也能推出来)
5. java内存结构分析

练习:分析以下代码会出现怎样的结果
(b指向null,可是a并没有,a仍然指向该对象,只要该对象还有指向它的,就不会被回收)
6. 成员方法的调用机制
只要调用一个方法就会产生一个新的栈

返回之后这个栈(名字不是真的叫gersum栈,只是为了理解方便)就会被销毁,就是这个空间被释放了/回收了/没有了。将得到的值(res)返回赋值给调用它的地方。

当main方法也结束了之后,main栈空间也被回收

ps:java在什么情况下发生自动类型转换
7. 成员方法传参机制(基本数据类型)
这两个栈是独立的,而且传递的参数是基本数据类型,在swap中形参的改变不影响实参。

8. 成员方法传参机制(引用数据类型)


9. 怎么判断对象是不是同一个
- 可以通过输出对象的hashcode看看对象是否是同一个
- 通过对象比较 if(p1==p2)
四、递归
1. 简单的递归分析
2. 递归重要规则
3. 汉诺塔代码
五、一些知识点
1. 方法重载

返回类型相同与否都没关系,关键是f选项中的参数列表是一样的。所以不能构成方法重载,这样是方法重新定义了,会报错。
2. 可变参数



注意细节

可以直接传数组进去
3. 作用域



结合jvm内存机制理解,say方法用的时候会在栈中创建,用完之后就销毁该方法占用的空间了,其内的变量也就自然而然没了。

4. 构造方法/构造器

注意这里,构造器不是创建一个对象,而是在创建了一个对象之后,对对象的属性进行初始化,比如填值。


每次的new XX()其实都会调用默认无参构造器

反编译发现确实会有这样的构造器

如果没有显式定义无参构造器,只有有参的构造器,当你new Dog()的时候立刻报错,因为原先的无参构造器已经被覆盖掉了,要是你还想用,就需要定义出来。

5. 对象创建的流程分析
在这里实际上属性被三次初始化了,第一次是建造对象时,默认初始化age=0,name=null;第二次是成员变量显式定义初始化,age=90,name=null;第三次是使用构造器,name=“小倩”,age=20。

这里还要再次强调,p是对象的引用,也可以说是对象名,但它不是对象,真正的对象在堆里面。
6. this关键字
1) 引入
这样的话实际上属性并没有被赋值,所以需要this
2) this关键字的jvm内存理解(this本质)
3) 小结
关于第四点
7. 包

8. 访问修饰符
六、 封装

七、 继承
1. 关系图
2. 注意细节


在子类初始化的时候默认调用super(),只不过是隐式的,没让我们看见而已



3. 继承内存布局

那当我想访问name的时候,访问到的是哪个呢?
答:从后往前找,有这个属性并且可以访问的话就返回。

如果遇到一个属性能找到,但是它是私有的,直接报错,不再往上找。
4. 练习
在这里,B类无参构造器因为有this所以没有super,但是它的有参构造器是有super的。
5. super关键字



属性和方法的规则一样

6. 方法重写/覆盖


八、多态
1. 介绍


2. 注意细节
1)向上转型


重点:属性(成员变量)看编译类型,成员方法看运行类型!!!!!!!!!!
2)向下转型


注意 这里父类引用必须指向的是当前目标类型的对象,即Animal animal=new Cat(),animal本来在内存中就是指向一个Cat对象的!
3)属性的值

4)instanceOf
3. 一些练习

第五个容易错哦,注意规则是:
属性看编译类型(等号左边),方法看运行类型(等号右边)。
4. java的动态绑定机制
1) 问题引入
如果这样的话,大家都能理解答案是为什么。

但是如果我现在去掉子类的sum方法,它自然就会想要往父类去找sum方法,而父类的sum方法里面要调用getI()方法,那么父类调用getI方法是父类的还是子类的呢?
2) 定义

由于规则1,上面引入问题的答案就应该是,它会去调用子类的getI方法!!结果a.sum()=30。
那如果这次又去掉子类的sum1方法呢?

由于规则2,现在调用到的sum1是父类的方法,而属性又没有动态绑定机制,所以i是父类的i,答案就是20。
那现在如果又没有了子类的i,a.sum()会返回什么?

根据上面的分析,调用a.sum的时候它会去调用父类的sum方法,父类又由于动态绑定机制规则1会去调用子类的getI方法,而子类的getI方法想要调用属性i,但是现在子类B中并没有i这个成员变量,它就又往上去查找,找到父类的i,所以答案是20。
5. 多态数组

具体可以看自己的代码
(D:\Project\JavaBasic\src\main\java\com\XXX\polymorphicArray)
如果想要调用每个类的特有方法
6. 多态参数

九、Object类详解
1. equals()
1)equals和==的区别



2)如何重写equals
首先,如果不重写,我们在比较的时候,由于本类没有equals方法,它去找父类,Person没有继承其他父类,那就只能找到Object,而Object的equals源码只是比较两个对象是否一样,即内存地址是否一样,那自然不一样,返回false。


所以我们就需要去重写Object的equals方法。

基本数据类型判断的是值是否相等,==是比较运算符,也是运算的一种,不同数据类型运算时,先转成精度最大的一种比较,byte short char先转成int再做运算。
2. hashcode()
3. toString()
全类名就是包名+类名

4. finalize

5. 断点调试



