java学习笔记

java学习 asleer 2022/6/27

前言

程序员的重要能力

想成为大佬,就是要通过学习和积累,提升自己的各方面能力,比较抽象,共勉!

  1. 团队协作能力

  2. 高效沟通能力

  3. 需求分析能力

  4. 架构设计能力

  5. 抽象复用能力

  6. 独立创造能力

  7. 问题解决能力

  8. 归纳总结能力

  9. 自主学习能力

  10. 工具利用能力

  11. 高效编码能力

  12. 信息检索能力

  13. 开源建设能力

  14. 源码阅读能力

  15. 自测审查能力

  16. 文档编写能力

  17. 知识表达能力

  18. 绘图描述能力

  19. 兴趣驱动(长期学习能力)

  20. 保持好奇心

  21. 其他

    • 复制粘贴能力
    • 打架能力
    • PPT 制作能力

高效法则

  1. 不要过分追求完美,完成比完美更重要。
  2. 有现成的代码,就不要自己写,避免重复劳动(学习除外)。
  3. 学会使用软件及快捷键来提升自己的编码效率。
  4. 做项目前,要先想清楚怎么做,做好充分的预研和设计。这样不仅便于后续的程序扩展,也能避免无意义的返工。
  5. 将大的目标进行拆解,做好计划,分清主次。不要因为觉得目标遥不可及而拖延,也不要盲目乐观而松懈。
  6. 养成好的作息习惯,找到自己适合工作的黄金时间。
  7. 记性不好,就多记录、多总结、定期复习。哪怕实在记不住,也可以借助文档、收藏夹软件来当自己的第二大脑。
  8. 积累属于自己的工具库,配合搜索软件实现随用随取。
  9. 多和其他同行交流或订阅技术推送,拓宽知识渠道,从而了解更多的工具和方法。有些东西你只要听说过,要用时也许就能节省大量查找时间。
  10. 找到让自己进入专注做事的状态的方法,比如戴上耳机、嚼口香糖等。
  11. 做事高效,离不开经验的积累,因此要多写代码、多做项目。

阶段1:java入门

java编程基础(45天)

学习资源

学习笔记


chapter1-1(学前须知)

JDK,JRE,JVM的关系
  1. JDK = JRE + java开发工具
  2. JRE = JVM + 核心类库
环境变量path的配置及作用
  1. 为了在dos的任意目录可以使用java和javac命令
  2. 先配置JAVA_HOME= 指向jdk安装的主目录
  3. 编辑path环境变量,增加%JAVA_HOME%\bin
java编写步骤
  1. 编写java的源代码
  2. javac编译,得到对应的.class字节码文件
  3. java运行,本质就是把.class加载到jvm运行
java转义字符

在命令台使用table可以实现命令补全

  1. \t:一个制表位,实现对齐的功能
  2. \n:换行符
  3. \\:一个\
  4. \":一个''
  5. \':一个'
  6. \r:一个回车(光标会到本行的最前面)

中文符号不需要转义,英文符号需要

注释(comment)
代码规范
  1. 类、方法的注释,要以javadoc的方式去写
  2. 非javadoc注释,往往是给维护者看的,着重告诉读者为什么这么写,如何修改,注意什么问题等
  3. 使用tab操作,实现缩进,默认整体向右边移动,shift+tab整体向左边移动
  4. 操作符和 = 两边习惯性各加一个空格
  5. 源文件使用utf-8编码
  6. 行宽度不超过80字符
  7. 代码编写次行风格和行尾风格(推荐)
dos命令(了解)
相对路径与绝对路径图解:

image-20220628100843124

常见dos命令
  1. dir:查看当前目录有什么内容

  2. cd:切换到其他盘,切换到c盘:cd /D c:

  3. 切换到当前盘的其他目录,看上图所示,两种写法

  4. cd ..:切换到上一级

  5. cd \:切换到根目录

  6. tree:查看指定目录下的自己目录

  7. cls:清屏

  8. 退出dos exit

  9. 了解内容:

    • md:创建目录
    • rd:删除目录
    • copy:拷贝文件
    • del:删除文件
    • echo:输入内容到文件echo ok > hello.txt
    • type,move:剪切

    主要用于Linux


chapter1-2(变量)

变量

类型+名称+值

for example:int a = 1;

计算机分配一个内存存储数值1,a是访问这个内存的方式(地址)

变量使用注意事项
程序中+号的使用

image-20220628153620197

数据类型(会背)
整数类型
浮点类型
字符类型

char:表示单个字符,可以存放汉字,多个字符使用字符串String

使用细节:

  1. 字符常量使用单引号括起来的单个字符
  2. 允许使用转义字符来将其后的字符转变为特殊字符型常量 \n 表示单个字符
  3. char本质是一个整数,在默认输出时,是unicode码对应的字符。要输出对应的数字可以 (int) 字符
  4. char类型是可以进行运算的,相当于一个整数,因为它都对应有unicode码。System.out.println('a'+10) = 107

本质:

布尔类型

介绍:boolean类型数据只允许取值true和false,占用1个字节。不能用0或非0的整数替代。

基本数据类型转换
自动类型转换

精度小的类型自动转换为精度大的类型。

数据类型按精度大小排序

char => int => long => float => double

byte => short => int => long => float => double

自动类型转换注意和细节

  1. 多种类型数据混合运算,自动将所有数据转换成容量最大的那种数据类型,然后再进行计算
  2. 精度大的数据类型不能赋值给精度小的数据类型
  3. (byte,short)和char之间不会相互自动转换
  4. byte,short,char他们三者不论是互相间运算还是自己运算,都会在计算时首先转换为int类型。
  5. boolean不参与类型的自动转换
强制类型转换

自动类型转换的逆过程,将容量大的数据类型转换为容量小的数据类型,使用时要加上强制转换符( ),但可能造成精度降低或外溢,格外要注意

基本数据类型和String类型的转换

基本数据类型 => String:n + ""

String => 基本数据类型:

通过基本类型的包装类调用parseXX方法即可

使用基本数据类型对应的包装类的相应方法,得到基本数据类型

字符串之间的比较方式
java API 文档

中文在线文档:Java 8 中文版 - 在线API中文手册 - 码工具 (matools.com)

使用方式:

  1. 直接索引
  2. 按照组织形式找:

image-20220628183734164


chapter1-3(运算符)

运算符
算数运算符

image-20220629094847922

  1. % 取模的本质:a % b = a - a / b * b,如果a是小数,则 a % b = a - (int)a / b * b

  2. 自增++:

    • 独立使用时:i++; == ++i; == i = i +1;

    • 作为表达式使用:

      • 前++:++i先自增后赋值
      • 后++:i++先赋值后自增
关系运算符

image-20220629100728237

结果都是boolean,注意不要把 == 写成 =

逻辑运算符

image-20220629101509819

赋值运算符
三元运算符
运算符的优先级

image-20220629151135920

标识符
标识符的命名规则和规范
进制
介绍

二进制:binary

四种表示方式:

  1. 二进制:0,1,满2进1,以0B或0b开头
  2. 十进制:0-9,满10进1
  3. 八进制:0-7,满8进1,以0开头
  4. 十六进制:0-9及A(10)-F(15),满16进1,以0X或0x开头,不区分大小写
进制的转换(基本功)
原码、反码、补码(重点、难点)

对于有符号的而言:

  1. 二进制的最高位是符号位:0表示正数,1表示负数
  2. 正数三码合一
  3. 负数的反码 = 负数的原码符号不变,其他位取反
  4. 负数的补码 = 负数的反码 + 1
  5. 0的反码,补码也是0
  6. java没有无符号数
  7. 计算机以补码的方式来运算的
  8. 当我们看运算结果的时候,要看它的原码

~2 = ?

2的原码等于补码:00000000 00000000 00000000 00000010

~2的补码:11111111 11111111 11111111 11111101

~2的反码:11111111 11111111 11111111 11111100

~2的原码:10000000 00000000 00000000 00000011

所以答案为-3

位运算符

chapter1-4(控制结构)

顺序控制

程序按顺序从上到下进行执行

分支控制(if,else,switch)
if,else分支结构

switch和if的比较

  1. 如果判断的具体数值不多,而且符合六种数据(byte,short,int,char,enum[枚举],String)类型,虽然两个语句都可以,但是建议使用switch语句
  2. 其他情况:对区间判断,对结果为boolean类型判断,使用if,if的使用范围更广
switch

需要注意的细节:

循环控制(for,while,do while,多重循环)
for

使用细节:

while
do while
break

用法:用于终止某个语句块的执行,等于跳出本次循环,一般使用在switch或者循环中。

continue

用法:用于结束本次循环,继续执行下一次循环

return

用法:使用在方法,表示跳出所在的方法;如果return写在main方法,退出程序


chapter1-5(数组array、排序和查找)

数组
定义
注意事项和细节
  1. 数组内数据赋值同样遵守自动类型转换

  2. 数组中的元素可以使任何数据类型,包括基本数据类型和引用数据类型,但不能混用

  3. 数组创建后,如果没有赋值,有默认值:

    • int,short,byte,long:0
    • float,double:0.0
    • char:\u0000
    • boolean:false
    • String:null
  4. 数组的下标从0开始

  5. 数组的下标必须在指定范围内使用,否则报:下标越界异常

数组赋值原理

image-20220701145928445

数组扩容
排序

将多个数据依指定的顺序进行排列的过程

冒泡排序法(Bubble Sorting)

思想:通过对待排序序列从后向前,依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就像水底下的气泡一样逐渐向上冒

查找

常用的查找:

多维数组 — 二维数组

dimensional:维数

动态初始化

chapter1-6(面向对象编程||初级)(类与对象object)(OOP)

类与对象的解释
类与对象的关系

把所有猫的特性(属性)提取出来 ===>

猫类Cat:自定义的数据类型,包含:

===> 猫对象:具体的一只猫,而不再是一个种类

类与对象的创建形式
对象在内存中的存在形式

image-20220702152128454

栈里的cat是对象的名字,堆里空间与数据才是真正的对象

java内存的结构分析

  1. 栈:一般存放基本数据类型(局部变量)
  2. 堆:存放对象(Cat cat,数组等)
  3. 方法区:常量池(常量,比如字符串),类加载信息

java创建对象的流程简单分析

  1. 先加载Cat类信息(属性和方法信息,只会加载一次)
  2. 在堆中分配空间,进行默认初始化(看规则)
  3. 把地址赋给cat,cat就指向对象
  4. 进行指定初始化
属性的使用
对象分配、赋值机制

类似于数组

image-20220702155513696

成员方法(method)
方法入门
方法的定义和细节

使用细节:

形参列表的细节:

方法调用细节:

方法调用机制

image-20220702215628664

方法传参机制

parameter:参数

基本数据的传参机制

引用数据的传参机制

方法递归(recursion)调用

递归就是方法自己调用自己,每次调用时传入不同的变量,递归有助于解决复杂的问题,同时让代码变得更简洁

image-20220703151549350

递归的重要规则

  1. 执行一个方法时候,就会创建一个新的受保护的独立栈空间
  2. 方法的局部变量是独立的,不会相互影响
  3. 如果方法中使用的是引用数据类型,就会共享该引用类型的数据
  4. 递归必须向退出递归的条件逼近,不然就无限递归了
  5. 方法执行完毕,或者遇到return,就会返回,遵守谁调用,就将结果返回给谁。
老鼠走迷宫问题
汉罗塔问题
八皇后问题

 

方法重载(overload)

定义:java中允许同一个类中,多个同名方法的存在,但要求形参列表不一致

注意事项:

可变参数

定义:java允许将同一个类中多个同名同功能但参数个数不同的方法,封装成同一个方法

注意事项:

作用域(scope)

基本使用

  1. 在java编程中,主要的变量就是属性(成员变量)和局部变量

  2. 局部变量一般指的是在成员方法中定义的变量(或代码块)

  3. java中作用域的分类

    • 全局变量:也就是属性,作用域为整个类体
    • 局部变量:也就是除了属性外的其他变量,作用域为定义它的代码块中
  4. 全局变量可以不赋值,直接使用,因为有默认值;局部变量必须赋值后才能使用,因为没有默认值

注意事项:

  1. 属性和局部变量可以重名,访问时遵循就近原则

  2. 在同一个作用域中,比如在同一个成员方法中,两个局部变量不能重名

  3. 作用域范围不同

    • 全局变量/属性:可以被本类使用,或被其他类使用
    • 局部变量:只能在本类中对应的方法中使用
  4. 修饰符不同

    • 全局变量/属性可以加修饰符
    • 局部变量不可以加修饰符
构造器/构造方法(constructor)

定义:是类的一种特殊方法,作用是完成对新对象的初始化。构造器对于方法较多的情况下非常好用。

基本语法

使用细节:

  1. 一个类可以定义多个不同的构造器,及构造器重载
  2. 构造器名和类名必须相同
  3. 构造器是完成对象的初始化,不是创建对象
  4. 构造器没有返回值
  5. 修饰符可以是默认,也可以是其他,一般用public
  6. 在创造对象时,系统会自动调用该类的构造器完成对对象的初始化
  7. 如果程序员没有定义构造器,系统会自动给类生成一个默认无参构造器(也叫默认构造器),比如Person(){},使用javap指令可以反编译查看
  8. 一旦定义了自己的构造器,默认构造器就被覆盖了,除非显示的定义一下:Person(){}(这点很重要)
对象创建的流程分析

看一个案例:

分析:

  1. 在方法区中先加载了Person类信息,只会加载一次

  2. 在堆中分配空间

  3. 完成对象初始化

    • 默认初始化:age = 0,name = null
    • 显式初始化:age = 90,name = null
    • 构造器初始化:age = 20,name = 小倩
  4. 把对象在堆中的地址返回给p(p是对象的引用)

This关键字

对象里面隐藏一个this属性,this属性指向方法自己。简单地说,哪个对象调用,this就代表哪个对象

使用细节:

比较两个人是否相同


chapter1-7(面向对象编程||中级)(IDEA,封装,继承,多态)

IDEA快捷键(ctrl+j)
普通快捷键
  1. ctrl+d:删除当前行
  2. ctrl+shift+向下光标:复制当前行
  3. alt+/:补全代码
  4. alt+enter:自动导入类
  5. ctrl+shift+L:快速格式化代码
  6. alt+R:快速运行程序
  7. alt+insert:生成构造器(esc+fn锁定F按键,或者alt+fn+insert)
  8. ctrl+H:查看一个类的层级关系
  9. ctrl+B:定位到方法
  10. .var:自动分配变量名
模板快捷键(template)
  1. main:主方法
  2. sout:输出
  3. fori:for循环

包的简单介绍:

访问修饰符(modifider)

java提供四种访问控制修饰符,用于控制方法和属性的访问权限(范围)

注意事项:

封装(encapsulation)
继承(extends)

image-20220706200635642

super关键字
方法重写/覆盖(override)
多态(polymorphic)

多态的细节讨论:

动态绑定机制(dynamic binding)
  1. 当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定(即优先调用子类的方法)
  2. 调用对象属性时,没有动态绑定机制,哪里声明哪里使用
Object类
equals方法
hashCode方法
  1. 提高具有哈希结构的容器的效率
  2. 两个引用,如果指向同一个对象则哈希值肯定是一样的,如果指向不同的对象则哈希值不一样
  3. 哈希值主要根据地址号来的,但不能完全将哈希值等价于地址
toString方法
finalize方法(已过期,开发中不会使用,应付面试)
断点调试(debug)

快捷键


chapter2-1(面向对象编程||高级)(静态成员,内部类)

类变量和类方法(static)
类变量
类方法
main方法

解释main方法的形式

  1. main方法是虚拟机调用的
  2. java虚拟机需要调用类的main()方法,所以该方法的访问权限必须是public
  3. java虚拟机在执行main()方法时不必创建对象,所以该方法必须是static
  4. 该方法接受String类型的数组参数,该数组中保存执行java命令时传递给所运行的类的参数:java 执行的程序名 参数1 参数2 参数3...
代码块
单例设计模式

介绍:采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法

小结:

  1. 饿汉式的问题:在类加载时候就创建了,可能存在资源浪费问题
  2. 懒汉式的问题:线程安全问题
final关键字
抽象类(abstract)
接口(interface)
内部类
局部内部类
匿名(anonymous)内部类!!!
成员内部类
静态内部类

chapter2-2(枚举和注解)

枚举类(enumeration)
自定义枚举
enum枚举类
Enum成员方法
JDK内置的基本注解(Annotation)类型
@Override
@Deprecated
@SuppressWarnings
JDK的元注解(了解)

chapter2-3(异常Exception)

异常
异常体系图

image-20220718202054541

常见的异常
异常处理
try—catch—finally
throws
自定义异常

chapter2-4(常用类)

包装类(Wrapper)
包装类方法
String类
结构剖析
创建方式
String对象特性
String类的常用方法
StringBuffer类
StringBuilder类
String相关类比较
Math类
  1. abs:绝对值

  2. pow:求幂指数

  3. ceil:向上取整

  4. floor:向下取整

  5. round:四舍五入

  6. sqrt:求开方

  7. random:求0~1内的随机数

    求2~7之间的一个随机整数

    (int)(2 + Math.random() * (5 + 1));

  8. max:求两个数的最大值

  9. min:求两个数的最小值

Arrays类
  1. toString:返回数组的字符串形式
  2. sort:排序,自然排序和定制排序
  1. binarySearch:通过二分搜索法进行查找,要求必须是排好序的数组。如果数组中不存在该元素,就返回return -(low + 1);
  2. copyOf:数组元素的复制。Arrays.copyOf(arr, arr.length()); 从arr数组中,拷贝arr.length个元素到新数组中。如果拷贝的长度>arr.length就在新数组的后面增加null。如果拷贝长度<0,就抛出NegativeArraySizeException。该方法的底层使用的是System.arraycopy()
  3. fill:数组元素的填充(替换原来数组的所有元素)
  4. equals:比较两个数组元素内容是否完全一致
  5. asList:将一组值,转换成list。List asList = Arrays.asList(2, 3, 4, 5, 6, 1);返回的asList编译类型是List(接口),运行类型是java.util.Arrays$ArrayList,是Arrays类的内部类
System类
BigInteger类和BigDecimal类
日期类
第一代日期类
第二代日期类
第三代日期类

chapter2-5(集合)

接口框架体系

image-20220722093619336

image-20220722094036219

开发中如何选择集合类

在开发中选择什么集合实现类,主要取决于业务特点

  1. 先判断存储的类型:一组对象(单列)或一组键值对(双列)

  2. 一组对象:Collection接口

    • 允许重复:List

      • 增删多:LinkedList:底层维护了一个双向链表
      • 改查多:ArrayList:底层维护了Object类型的可变数组
    • 不允许重复:Set

      • 无序:HashSet:底层是HashMap,维护了一个哈希表(数组+链表+红黑树)
      • 排序:TreeSet
      • 插入和取出顺序一致:LinkedHashSet:维护数组和双向链表
  3. 一组键值对:Map

    • key无序:HashMap:底层是哈希表(数组+链表+红黑树)
    • key排序:TreeMap
    • 键插入和取出顺序一致:LinkedHashMap
    • 读取文件:Properties
Collection
LIST

ArrayList

Vector

LinkedList

Set

HashSet

LinkedHashSet

Map

image-20220724101041265

HashMap
LinkedHashMap
Hashtable
Properties
TreeSet和TreeMap
Collections工具类
面试题
  1. 试分析HashSet和TreeSet分别如何实现去重的

    • HashSet去重机制:Hashcode()+equals(),底层先通过传入一个对象,获得一个hash值,通过hash值得到一个对应的索引,如果在table表索引位置没有数据则直接存放进去,如果存在数据则在链表或红黑树内进行equals遍历比较,如果相同就放弃添加,如果不同就添加到最后
    • TreeSet去重机制:如果你传入一个Comparator匿名对象,就使用实现的compare去重,如果方法返回0就认为是相同元素不进行添加,如果你没有传入一个Comparator匿名对象,则以你添加的对象实现的Compareable接口的compareTo去重。(如果添加的对象没有实现Compareable接口,则会抛出ClassCastException)

chapter2-6(泛型generic)

泛型语法
自定义(custom)泛型
泛型类
泛型接口
泛型方法
泛型继承和通配符

chapter2-7(线程基础)

线程基础
线程使用
继承(Thread)
实现(Runnable)
线程方法
线程生命周期

image-20220729115934727

Synchronized
互斥锁
死锁
释放锁

chapter2-8(IO流)

文件
IO流原理以及流的分类

IO流体系图

节点流和处理流
节点流和处理流

节点流和处理流

标准输入输出流
转换流(transformation)

image-20220801102125077

打印流

image-20220801105346981image-20220801105612030

可以看到PrintStream可以输入文件,字符串,字节流,PrintWriter可以放入文件,字符串,字节流,字符流

字节流
InputStream:字节输入流图示

image-20220731085533228

OutputStream:字节输出流图示

image-20220731110950558

字符流
Reader:字符输入流和Writer:字符输出流
Properties类

chapter3-1(网络编程)

网络相关概念
ip地址
  1. 概念:用于唯一标识网络中的每台计算机/主机
  2. 查看ip地址:ipconfig
  3. ip地址的表示形式,点分十进制:xx.xx.xx.xx,每一个十进制数的范围0~255。(IPV4,4字节(32位)表示)
  4. ip地址的组成=网络地址+主机地址,比如192.168.16.69,前三个为网络地址,最后为主机地址
  5. IPV6(16字节(128位)表示)是互联网工程任务组设计的用于替代IPV4的下一代IP协议

image-20220801215717463

域名和端口号

image-20220801221230896

网络通信协议

image-20220801223722181

image-20220801223824212

InetAddress类
Socket

image-20220802095330985

TCP网络通信编程
TCP字节流编程

image-20220802111347343

image-20220802155347335

TCP字符流编程

image-20220802162921762

netstat指令
UDP网络通信编程

image-20220803090142184

练习题
加载图片到内存
下载歌曲

chapter3-2(反射Reflection)

反射机制

image-20220807220052074

Class类

image-20220807194422875

Class常用方法
获取Class类对象
  1. Class.forName()

    • 前提:已知类的全类名(全路径),且在该类的类路径下,可通过Class类的静态方法forName获取,可能抛出ClassNotFoundException
    • 应用场景:多用于配置文件,读取类全路径,加载类
    • 实例:Class<?> aclass = Class.forName("chapter3_2.Car");
  2. 类名.class

    • 前提:若已知具体的类,通过类的class获取,该方式最为安全可靠,程序性能最高
    • 应用场景:多用于参数传递,比如通过反射得到对应构造器对象
    • 实例:Class<Car> carClass = Car.class;
  3. 对象名.getClass()

    • 前提:已知某个类的实例,调用该实例的getClass()方法获取Class对象
    • 应用场景:通过创建好的对象,获取Class对象
    • 实例:Class<? extends Car> aClass = car.getClass();
  4. 类加载器

    • 实例:

  5. 基本数据类型

    • Class<Integer> integerClass = int.class;
    • 会实现自动装箱和拆箱,输出为int
  6. 基本数据类型对应的包装类

    • Class<Character> type = Character.TYPE;
    • 会实现自动装箱和拆箱,输出为char
  7. 如下成员有Class对象

    • 外部类、内部类
    • interface
    • 数组
    • 枚举enum.state
    • annotation注解
    • void
类加载
类加载流程图

image-20220808161915104

image-20220808161948629