目录

韩顺平-零基础30天学会Java第一阶段自用

目录

【韩顺平 零基础30天学会Java】(第一阶段)(自用)

目录

一、一维数组

1. 变量名指向地址

https://i-blog.csdnimg.cn/blog_migrate/1a2833f78df3b908d8dea172560bade4.png

2. 数组新建和输入

https://i-blog.csdnimg.cn/blog_migrate/703eb8074fd906b21850e3a89942b8d1.png

3. 数组可以先声明后分配

https://i-blog.csdnimg.cn/blog_migrate/d697ce5325ae8e370969bc7bdfc6cf01.png

这种情况的话实际上是先new了一个指针a,a此时指向null,后面再将a指向new int[3]分配的空间

https://i-blog.csdnimg.cn/blog_migrate/a1e7a68550814098856f2e9fb8c3a10c.png

4. 静态初始化

https://i-blog.csdnimg.cn/blog_migrate/e4199c24da95787d5b95b4144c1914ea.png

5. 数组使用的一些注意细节

https://i-blog.csdnimg.cn/blog_migrate/6fd683bd1106d0703dc7e08478e7e586.png

6. 值传递和引用传递的区别

https://i-blog.csdnimg.cn/blog_migrate/763761fe384e5518e65144cd681aefb7.png

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

https://i-blog.csdnimg.cn/blog_migrate/4ed7284e3d86fc3c859a0dd15a08bd75.png

7. 数组拷贝

https://i-blog.csdnimg.cn/blog_migrate/eac8ae821e8526ba8ae343722a293995.png https://i-blog.csdnimg.cn/blog_migrate/c0bd2d11bbcfceedadf90b93455cab3b.png

8. 数组的扩容

https://i-blog.csdnimg.cn/blog_migrate/6fd0b7136255e8d243176e4aafa4b33f.png

https://i-blog.csdnimg.cn/blog_migrate/d343b751c0ce9e85b0404a83b5bc3ef0.png

二、 二维数组

1. 动态初始化

https://i-blog.csdnimg.cn/blog_migrate/e43f769cb9116772ad51cd3e64847644.png

2. 内存存在形式

https://i-blog.csdnimg.cn/blog_migrate/3fc6669f0a6938dee7bf7637f681f769.png

https://i-blog.csdnimg.cn/blog_migrate/594ae79f138d87a04e084ac7e78680d1.png

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

https://i-blog.csdnimg.cn/blog_migrate/8190723ef2d104c9493d558e4c22204e.png

遍历的时候才真正开空间

https://i-blog.csdnimg.cn/blog_migrate/dadd5d63d9daa5f37adb851264e3c0d4.png

4. 静态初始化

https://i-blog.csdnimg.cn/blog_migrate/8eb8f217496e1da4b736a928fdabf4a5.png

5. 二维数组的注意细节

https://i-blog.csdnimg.cn/blog_migrate/caba61e306b43107ec2c46ada4995172.png

6. 对数组声明和初始化的理解练习

https://i-blog.csdnimg.cn/blog_migrate/f6cb44f148f9506c8c71999bef8af9cc.png

三、面对对象基础篇

1. 内存中对象的存在形式

https://i-blog.csdnimg.cn/blog_migrate/07d54c8551713f130c06e518cd4e6a77.png

2. 成员变量的注意细节

https://i-blog.csdnimg.cn/blog_migrate/b0fa094682fc68fc603a9cdd6e851742.png

ps:基本数据类型和引用类型

https://i-blog.csdnimg.cn/blog_migrate/f9dc88e72fe37757d34dc582ac30aab9.png

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

https://i-blog.csdnimg.cn/blog_migrate/5b88e1852108687f7bd393ffce240e70.png

注意 p1只是 对象名,new出来的空间才是真正的对象

就比如小明和李明都是这个人的名字而已,并不是他自己

https://i-blog.csdnimg.cn/blog_migrate/537d146e68380ebb4cc46488d2220c73.png

3. 创建对象的方法

先声明对象cat,此时cat指向null,等new cat的时候,在堆中创建空间,然后将该空间的地址比如OX1122赋值给cat,cat就指向了OX1122的这个空间,即指向了这个对象。

https://i-blog.csdnimg.cn/blog_migrate/9adc4532404d049eb88927b757d8b0c1.png

4. 类和对象的内存分配机制

https://i-blog.csdnimg.cn/blog_migrate/e5aaac05d2914ba41efb58a2c1c67650.png

执行第一行代码

https://i-blog.csdnimg.cn/blog_migrate/524faf17f497e938f944aa5e6eab75ea.png

执行第二行代码

https://i-blog.csdnimg.cn/blog_migrate/d05380af29cd1aaf4deeb4a1fe8ff720.png

执行第三行代码

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

https://i-blog.csdnimg.cn/blog_migrate/489ef10f8f96a3e70a32baddca3fca4c.png

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

https://i-blog.csdnimg.cn/blog_migrate/e319d3a594044a1b3a7ee93beb9c6736.png

5. java内存结构分析

https://i-blog.csdnimg.cn/blog_migrate/71d222759b6d4aa6b7e99126556d206b.png

练习:分析以下代码会出现怎样的结果

(b指向null,可是a并没有,a仍然指向该对象,只要该对象还有指向它的,就不会被回收)

https://i-blog.csdnimg.cn/blog_migrate/7243a2dce605ece9f07b4681eb0da120.png

6. 成员方法的调用机制

只要调用一个方法就会产生一个新的栈

https://i-blog.csdnimg.cn/blog_migrate/2d45817016a62940b2a2ec5e36b4c067.png

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

https://i-blog.csdnimg.cn/blog_migrate/0da8868ed40014bc6da8e683657331d2.png

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

https://i-blog.csdnimg.cn/blog_migrate/225cd50251fa723073298a4c94bef59f.png

https://i-blog.csdnimg.cn/blog_migrate/95ec663fc1639bc2192adffe670a1bf5.png

ps:java在什么情况下发生自动类型转换

https://i-blog.csdnimg.cn/blog_migrate/e5d05fcd741de76d160b1b7667c1d2bc.png

7. 成员方法传参机制(基本数据类型)

这两个栈是独立的,而且传递的参数是基本数据类型,在swap中形参的改变不影响实参。

https://i-blog.csdnimg.cn/blog_migrate/c7b2ea30ade152c82af56eed3c576a89.png

https://i-blog.csdnimg.cn/blog_migrate/04207ae0b6502b6256ef9d55791c521e.png

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

https://i-blog.csdnimg.cn/blog_migrate/7b6ecca8ea63bb359fee8ffad62ad535.png

https://i-blog.csdnimg.cn/blog_migrate/3dd6df7d7075e1e5c2ade6965133de3d.png

https://i-blog.csdnimg.cn/blog_migrate/6e44b5d46bb99b624c0b73651be3bbe1.png

9. 怎么判断对象是不是同一个

  1. 可以通过输出对象的hashcode看看对象是否是同一个
  2. 通过对象比较 if(p1==p2)

四、递归

1. 简单的递归分析

https://i-blog.csdnimg.cn/blog_migrate/c4e1057ecc842246136f942005394517.png

2. 递归重要规则

https://i-blog.csdnimg.cn/blog_migrate/527d335391639bb51f5fc723e9fdc104.png

3. 汉诺塔代码

https://i-blog.csdnimg.cn/blog_migrate/3bf09d6d952ed2a89630c0cf43a410f7.png

五、一些知识点

1. 方法重载

https://i-blog.csdnimg.cn/blog_migrate/dbc44c1bc6eb7d058b1712a446a4ab1b.png

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

https://i-blog.csdnimg.cn/blog_migrate/76b635d26c0b293958c8166490bef572.png

2. 可变参数

https://i-blog.csdnimg.cn/blog_migrate/55b6c253dde6edbea6c85fa0fdaf5c6c.png

https://i-blog.csdnimg.cn/blog_migrate/7a53284a49f9c9cf42a4d19409ceb1ed.png

https://i-blog.csdnimg.cn/blog_migrate/db8904002f6f9f522fea74e6c200d927.png

注意细节

https://i-blog.csdnimg.cn/blog_migrate/5f3829b39108e2e34dd3e459b8cc0318.png

可以直接传数组进去

https://i-blog.csdnimg.cn/blog_migrate/41348503efe13d25a91fdfb0efab8a67.png

3. 作用域

https://i-blog.csdnimg.cn/blog_migrate/0c4ac2117dbfefd5aff560a1aefa4174.png

https://i-blog.csdnimg.cn/blog_migrate/2ba5a89765ee999479439aa519949428.png

https://i-blog.csdnimg.cn/blog_migrate/30f820c6902d0dc222a476d541f97cc8.png

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

https://i-blog.csdnimg.cn/blog_migrate/3354e930a7ae6de18896feb1830e6184.png

https://i-blog.csdnimg.cn/blog_migrate/0bc296cb73a7b64d85f67b23ac843b29.png

4. 构造方法/构造器

https://i-blog.csdnimg.cn/blog_migrate/fbb49bad0c56f754d799a0113ff54f89.png

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

https://i-blog.csdnimg.cn/blog_migrate/1a7336c0639f94016e04f23c81a51cde.png

https://i-blog.csdnimg.cn/blog_migrate/eeac689c79a49836e4f62da6e1716d07.png

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

https://i-blog.csdnimg.cn/blog_migrate/481d32595a79c40d41728153cebf549f.png

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

https://i-blog.csdnimg.cn/blog_migrate/2718428bb191534db760faa5cfaa1fc6.png

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

https://i-blog.csdnimg.cn/blog_migrate/b5233c3ffff8fcb8587435c5ff2350b5.png

https://i-blog.csdnimg.cn/blog_migrate/4421c1054f37ccfded4cb240b96efc18.png

5. 对象创建的流程分析

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

https://i-blog.csdnimg.cn/blog_migrate/e33e174b8072a728e70a22473d7a7a61.png

这里还要再次强调,p是对象的引用,也可以说是对象名,但它不是对象,真正的对象在堆里面。 https://i-blog.csdnimg.cn/blog_migrate/9bd188d0c7cc4ac1514961148fa6fa17.png

6. this关键字

1) 引入

这样的话实际上属性并没有被赋值,所以需要this

https://i-blog.csdnimg.cn/blog_migrate/97c06d885f0039737db36a0e8f008f94.png

2) this关键字的jvm内存理解(this本质)

https://i-blog.csdnimg.cn/blog_migrate/117c969597c5f223fd6b35107e1d08ca.png

3) 小结

https://i-blog.csdnimg.cn/blog_migrate/98352d5577598943d93e978e7372d26d.png

关于第四点

https://i-blog.csdnimg.cn/blog_migrate/1b46daa19b9653f280ada7d560a49403.png

7. 包

https://i-blog.csdnimg.cn/blog_migrate/a3a583082e79a7ebc8e7b85ea2e51228.png

https://i-blog.csdnimg.cn/blog_migrate/0d180cfa3bda23aef3ef740ac679ef35.png

8. 访问修饰符

https://i-blog.csdnimg.cn/blog_migrate/55ee1d13f4a593efb0b57379e92c94eb.png

六、 封装

https://i-blog.csdnimg.cn/blog_migrate/a56acbf4a229adcf63d7c4fd25859f43.png

https://i-blog.csdnimg.cn/blog_migrate/02eb6636f9fb999367341e31f532063f.png

七、 继承

https://i-blog.csdnimg.cn/blog_migrate/513555aa93d7546e8788d6aaf5436ab3.png

1. 关系图

https://i-blog.csdnimg.cn/blog_migrate/89410ea6d11a96afbbf6f7225dc5af0e.png

2. 注意细节

https://i-blog.csdnimg.cn/blog_migrate/9494e006e21365b6d0ca78cecb8df31f.png https://i-blog.csdnimg.cn/blog_migrate/b44bc91c532e1292aae6815bc15ddcab.png

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

https://i-blog.csdnimg.cn/blog_migrate/9274ef537194b69dc9666936079b1ea0.png

https://i-blog.csdnimg.cn/blog_migrate/03b645e5e7f6b802e4637942347fa659.png

https://i-blog.csdnimg.cn/blog_migrate/8c0d5e3dd356dbcc4c37c3bb7286b751.png

https://i-blog.csdnimg.cn/blog_migrate/8477d92afbc158c991a0d27402c23671.png

3. 继承内存布局

https://i-blog.csdnimg.cn/blog_migrate/964a6a57c93825540ef27d9d736df688.png

那当我想访问name的时候,访问到的是哪个呢?

答:从后往前找,有这个属性并且可以访问的话就返回。

https://i-blog.csdnimg.cn/blog_migrate/aedf8477c301d58f1f4725cc6e3c8e4f.png

如果遇到一个属性能找到,但是它是私有的,直接报错,不再往上找。

4. 练习

在这里,B类无参构造器因为有this所以没有super,但是它的有参构造器是有super的。

https://i-blog.csdnimg.cn/blog_migrate/8f6835e5bb2a869be1e3d354e575df65.png

5. super关键字

https://i-blog.csdnimg.cn/blog_migrate/009d44f5a2cdd5fcbcff7ed999265d6f.png

https://i-blog.csdnimg.cn/blog_migrate/4f94c895e24c85ad88527266ebb495fa.png

https://i-blog.csdnimg.cn/blog_migrate/0155a6cd6e6ed4ae58fda5dce80f1c46.png

属性和方法的规则一样

https://i-blog.csdnimg.cn/blog_migrate/696e6b423b68eb46caddcb2342e81e83.png

https://i-blog.csdnimg.cn/blog_migrate/7493ae541a712f7d1ff9cb8b28f64ff2.png

6. 方法重写/覆盖

https://i-blog.csdnimg.cn/blog_migrate/03316b716baf921154837e9f841dc0c6.png

https://i-blog.csdnimg.cn/blog_migrate/2a377b1f689838af192a28150daa98e8.png

https://i-blog.csdnimg.cn/blog_migrate/2452f79801c8edbc05ee7b42d2840d3b.png

八、多态

1. 介绍

https://i-blog.csdnimg.cn/blog_migrate/c6c9d470e48538c1bc48a52c3b1cfe30.png

https://i-blog.csdnimg.cn/blog_migrate/e5ec090f90d203bdff5f48b061deda23.png

https://i-blog.csdnimg.cn/blog_migrate/6a2316c8e8824b1d2f341644d5e2fa20.png

2. 注意细节

1)向上转型

https://i-blog.csdnimg.cn/blog_migrate/80eee97325a3f60a4b0e59fa4266f712.png

https://i-blog.csdnimg.cn/blog_migrate/1ed2153199e42a7e295e976b3abe315f.png

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

2)向下转型

https://i-blog.csdnimg.cn/blog_migrate/77039e756f2764e4d9ff7dd0ee51c3fe.png

https://i-blog.csdnimg.cn/blog_migrate/18fe6cd0ff9f2730453ce68e276d8cbe.png

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

https://i-blog.csdnimg.cn/blog_migrate/25f8ad6457a38606cb91bb17336c25ec.png

3)属性的值

https://i-blog.csdnimg.cn/blog_migrate/97f88385c8571a34983d5c299dea9a8f.png

https://i-blog.csdnimg.cn/blog_migrate/9bee790e37a7edd6aadae44a9ab4f189.png

4)instanceOf

https://i-blog.csdnimg.cn/blog_migrate/7544d02fe25242b73f363752b5d9a492.png

3. 一些练习

https://i-blog.csdnimg.cn/blog_migrate/2608f8454bea5ac7c3d891bd8c1031cc.png

第五个容易错哦,注意规则是:

属性看编译类型(等号左边),方法看运行类型(等号右边)。

https://i-blog.csdnimg.cn/blog_migrate/851a867d7edbbf5c62075157c86a1518.png

4. java的动态绑定机制

1) 问题引入

如果这样的话,大家都能理解答案是为什么。

https://i-blog.csdnimg.cn/blog_migrate/76c695ffe8641c1dff0d36f52c919a6e.png

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

https://i-blog.csdnimg.cn/blog_migrate/e3fc564bf47287069e2accbb8e09d038.png

2) 定义

https://i-blog.csdnimg.cn/blog_migrate/65acb1240ebb737ccdd4b8d7c39251c2.png

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

那如果这次又去掉子类的sum1方法呢?

https://i-blog.csdnimg.cn/blog_migrate/b9464b6945deba08f2b11996d12f9f80.png

由于规则2,现在调用到的sum1是父类的方法,而属性又没有动态绑定机制,所以i是父类的i,答案就是20。

那现在如果又没有了子类的i,a.sum()会返回什么?

https://i-blog.csdnimg.cn/blog_migrate/6dcb8e6cc5b4d2137f7973d8d2aa0336.png

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

5. 多态数组

https://i-blog.csdnimg.cn/blog_migrate/6918f2f2da90afad643104064a15b827.png

具体可以看自己的代码

(D:\Project\JavaBasic\src\main\java\com\XXX\polymorphicArray)

如果想要调用每个类的特有方法

https://i-blog.csdnimg.cn/blog_migrate/ba68534ee9d6092fd120a62ca60228a1.png

6. 多态参数

https://i-blog.csdnimg.cn/blog_migrate/6e2bd306f93d1b1f81eb884fdeb448f7.png

https://i-blog.csdnimg.cn/blog_migrate/e9a6f9692a76f1df70db144710a5446c.png

九、Object类详解

1. equals()

1)equals和==的区别

https://i-blog.csdnimg.cn/blog_migrate/d5a062fd3ccc005b83184bf4af4525b0.png

https://i-blog.csdnimg.cn/blog_migrate/1037f834cabd7c860466440c2c3631af.png

https://i-blog.csdnimg.cn/blog_migrate/97e763e304bebc165942a9f3f0ee50ee.png

https://i-blog.csdnimg.cn/blog_migrate/82804c12de628d09bcb48b1f61fc174b.png

2)如何重写equals

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

https://i-blog.csdnimg.cn/blog_migrate/50959c323778a2f93950abb398571d4b.png

https://i-blog.csdnimg.cn/blog_migrate/3aa368868ba77ef6e311dfa31f8e1fe9.png

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

https://i-blog.csdnimg.cn/blog_migrate/20d0d9b265368ff8b3c869cda41246c4.png

基本数据类型判断的是值是否相等,==是比较运算符,也是运算的一种,不同数据类型运算时,先转成精度最大的一种比较,byte short char先转成int再做运算。

https://i-blog.csdnimg.cn/blog_migrate/01608105a8d4065895122dd39ce50653.png

2. hashcode()

https://i-blog.csdnimg.cn/blog_migrate/aa4444d5c59ecc6e23502545d4499134.png

3. toString()

全类名就是包名+类名

https://i-blog.csdnimg.cn/blog_migrate/cb11e98dd096613f981c444253c8c742.png

https://i-blog.csdnimg.cn/blog_migrate/877fa4d9ba8a1c4ed35fb96782e41d15.png

4. finalize

https://i-blog.csdnimg.cn/blog_migrate/1f3bdeb88535cdd24a8a812e7d23d1c9.png

https://i-blog.csdnimg.cn/blog_migrate/9a6f396bdd79d503d4318b5563214639.png

https://i-blog.csdnimg.cn/blog_migrate/831d1a017dbfe946c9f7a780acb8515a.png

5. 断点调试

https://i-blog.csdnimg.cn/blog_migrate/601181d27d29dbeeee58166ea8e5fe32.png

https://i-blog.csdnimg.cn/blog_migrate/5018b2735cb83fe813f32065393e3967.png

https://i-blog.csdnimg.cn/blog_migrate/7b148b26afffca46f55803ef153747d8.png

https://i-blog.csdnimg.cn/blog_migrate/b3d53cf9e484d583e9242d7f3f896623.png

https://i-blog.csdnimg.cn/blog_migrate/6bb13c586cc29124d3ca87f3070a12ab.png