一、类和对象

1 面向对象编程(理解)

1.1 面向对象编程概念

  • 万物皆对象。
  • 面向对象指以属性和行为的观点去分析现实生活中的事务。
  • 面向对象编程指先以面向对象的思想进行分析,然后使用面向对象的编程语言进行表达的过程。
  • 面向对象编程是软件产业化发展的需求。
  • 理解面向对象的思想精髓(封装、继承、多态)。至少掌握-一种编程语言。

    2 类和对象及引用

    2.1 类和对象的概念

  • 对象主要指现实生活中客观存在的实体 ,在Java语 言中对象体现为内存空间中的一块存储区域。

  • 类简单来就是”分类” ,是对具有相同特征和行为的多个对象共性的抽象描述,在Java语言中体现为一种引用数据类型,里面包含 了描述特征/属性的成员变量以及描述行为的成员方法。
  • 类是用于构建对象的模板,对象的数据结构由定义它的类来决定。

2.2 类的定义

  • class 类名{

类体;
}

  • 注意:

通常情况下,类名使用驼峰式(多个字母组成,首字母大写)。

2.3 成员变量的定义

  • class类名{

    数据类型 成员变量名 = 初始值;
    }

  • 注意:

成员变量使用小驼峰式(第二个字母首字母大写)

2.4 对象的创建

  • new 类名();
  • 注意:

a.当一个类定义完毕后,可以使用new关键字来创建该类的对象, 这个过程叫做类的实例化。
b.创建对象的本质就是在内存空间的堆区申请一块存储区域 ,用于存放该对象独有特征信息。

2.5 引用的定义

  • 基本概念

a.使用引用数据类型定义的变量叫做弓|用型变量,简称为”引用”。
b.引用变量主要用于记录对象在堆区中的内存地址信息,便于下次访问。

  • 语法格式
  • 类名 引用变量名;

引用变量名.成员变量;

2.6 person案例

  • 编程实现Person的使用。

Person.java

成员变量的初始值

image.png

2.7 point案例

  • 编程实现Point类的定义,特征有:横纵坐标(整数) ,要求在main方法中声明Point类型的引用指向Point对象并打印特征,然后将横纵坐标修改为3和5后再次打印。

Point.java

3 成员方法(重要)

3.1 成员方法的定义

  • class类名{

返回值类型 成员方法名(形参列表){
成员方法体:
}
}

  • 当成员名多个单词组成时,要求小驼峰式(第二个单词起,每个单词的首字母大写)。

3.2 返回类型的详解

  • .返回值主要指从方法体内返回到方法体外的数据内容。
  • 返回值类型主要指返回值的数据类型,可以是基本数据类型,也可以是引用数据类型。
  • 当返回的数据内容是66时,则返回值类型写int即可
  • 在方法体中使用return关键字可以返回具体的数据内容并结束当前方法。
  • 当返回的数据内容是66时,则方法体中写return 66;即可
  • .当该方法不需要返回任何数据内容时,则返回值类型写void即可。

3.3 方法体详解

  • 成员方法体主要用于编写描述该方法功能的语句块。
  • 成员方法可以实现代码的重用,简化代码。

3.4 方法的调用

  • 引用变量名成员方法名(实参列表); p.show();
  • 实际参数列表主要用于对形式参数列表进行初始化操作,因此参数的个数、类型以及顺序都要完全一致。
  • 实际参数可以传递直接量、变量、表达式、方法的调用等。

3.5 可变长参数

  • 返回值类型方法名(参数的类型..参数名)
  • 方法参数部分指定类型的参数个数是可以改变的,也就是0~n个。
  • 一个方法的形参列表中最多只能声明一个可变长形参,并且需要放到参数列表的末尾。

3.6 方法的传参过程

image.png

3.7 参数传递的注意事项

  • .基本数据类型的变量作为方法的参数传递时, 形参变量数值的改变通常不会影响到实参变量的数值,因为两个变量有各自独立的内存空间;
  • 引用数据类型的变量作为方法的参数传递时,形参变量指向内容的改变会影响到实参变量指向内容的数值,因为两个变量指向同一块内存空间
  • 当引用数据类型的变量作为方法的参数传递时,若形参变量改变指向后再改变指定的内容,则通常不会影响到实参变量指向内容的改变,因为两个变量指向不同的内存空间。

3.8 内存结构之栈区

  • 栈用于存放程序运行过程当中所有的局部变量。一个运行的Java程序从开始到结束会有多次方法的调用。
  • JVM会为每一 个方法的调用在栈中分配一 个对应的空间,这个空间称为该方法的栈帧。一个栈帧对应一个正在调用中的方法,栈帧中存储了该方法的参数、局部变量等数据。
  • 当某一个方法调用完成后, 其对应的栈帧将被清除。

3.9 传参的相关概念

  • 参数分为形参和实参,定义方法时的参数叫形参,调用方法时传递的参数叫实参。
  • 调用方法时采用值传递把实参传递给形参,方法内部其实是在使用形参。
  • 所谓值传递就是当参数是基本类型时,传递参数的值,比如传递i=10,真实传参时,把10赋值给了形参。当参数是对象时,传递的是对象的值,也就是把对象的地址赋值给形参。

二、方法和封装

1 构造方法

1.1 构造方法的基本概念

  • class类名{

类名(形参列表){
构造方法体
}
}

  • 构造方法名和类完全相同并且没有返回值,连void不能有

1.2 默认构造方法

  • 当一个类中没有定义任何构造方法时,编译器会提供一个无参空构造方法,叫做默认/缺省构造方法,如:Person(){}
  • 若出现了构造方法,则编译器不再提供任何形式的构造方法。

1.3 构造方法的作用

  • 使用new关键字创建的对象时,会自动调用构造方法实现类成员的 变量初始化工作。

1.4 Ponit类案例

Point2.java

2 方法重载

2.1 方法重载的概念

  • 若方法名称相同,参数列表不同,这样的方法之间构成重载关系(Overload)。

2.2 方法重载的体现形式

  • 方法的重载主要体现在:参数的个数不同、参数的类型不同、参数的顺序不同,返回值类型和形参变量名无关,但是建议返回值最好相同(基于代码的可阅读性)
  • 判断方法是否构成重载的核心:调用方法时能否加以区分

    2.3 Ponit类案例(1.4相同)

    Point2.java

2.4 重载的实际意义

  • 方法重载的实际意义在于调用者需要记住一个方法名就可以调用各种不同的版本,来实现各种功能
  • 如:java.io.PrintStream类中的println方法。

3 this关键字

3.1 this的基本概念

  • 若在构造方法中出现了this关键字,则代表当前正在构造对象。
  • 若成员方法中出现了this关键字,则代表当前正在调用的对象。
  • this关键字本质上就是当前类类型的引用变量。

3.2 工作原理

  • .在构造方法中和成员方法中访问成员变量时,编译器会加上this的前缀,而this.相当于汉语中”我的” ,当不同的对象调用同一个方法时,由于调用方法的对象不同导致this关键字不同,从而this.方式访问的结果也就随之不同。

3.3 使用方式

  • 当局部变量名与成员变量名相同时,在方法体中会优先使用局部变量(就近原则) ,若希望使用成员变量,则需要在成员变量的前面加上this的前缀,明确要求该变量是成员变量(重中之重)。
  • this关键字除了可以通过this的方式调用成员变量和成员方法外,还可以作为方法的返回值(重点)。
  • 在构造方法的第一行可以使用this()的方 式来调用本类中的其它构造方法(了解)。

3.4 注意事项

  • 引用类型变量用于存放对象的地址,可以给引用类型赋值为null ,表示不指向任何对象。
  • 当某个弓|用类型变量为null时无法对对象实施访问(因为它没有指向任何对象)。此时,如果通过引用访问成员变量或调用方法,会产生NullPointerException异常。

4 方法递归调用

4.1 方法案例

  • 编程实现参数阶乘并返回,所谓阶乘就是从1累乘到n的结果。

JieChengTest.java

4.2 递归的基本概念

  • 递归的本质就是指在方法体的内部直接或者间接调用当前方法自身的形式。

4.3 注意事项

  • 使用递归必须有递归的规律以及退出条件。
  • 使用递归必须使得问题简单化而复杂化。
  • 若递归影响到程序的执行性能,则使用递推取而代之。

4.4 案例题目

  • 编程实现费式数列中第n项的数值并返回。
  • 费式数列:1 1 2 3 5 8 13 21 ……

Fee.java
FreeTest.java

5 封装

5.1 封装的概念

  • 通常情况下可以在测试类给成员变量赋值一些合法但不合理的数值 ,无论是编译阶段还是运行阶段都不会报错或者给出提示,此时与现实生活不符。
  • 为了避免上述错误的发生,就需要对成员变量进行密封包装处理,来隐藏成员变量的细节以及保证成员变量数值的合理性,该机制就叫做封装。

5.2 封装的实现流程

  • 私有化成员变量,使用private关键字修饰。
  • 提供公有的get和set方法,并在方法体中进行合理值的判断。
  • 在构造方法中调用set方法进行合理值的判断。

5.3 案例题目(学生信息)

  • 提示用户输入班级的学生人数以及每个学生的信息,学生的信息有:学号、姓名,最后分别打印。
  • 提示:Student[] aar = new Student[num];

Student.javaStudentTest.javaStudentTest2.java

5.3 JavaBean的概念

  • JavaBean是一 种Java语言写成的可重用组件,其它Java类可以通过反射机制发现和操作这些JavaBean的属性。
  • JavaBean本质上就是符合以下标准的Java类:

类是公共的
有一个无参的公共的构造器
有属性,且有对应的get、set方法

三、 Static关键字和继承

1 static关键字

1.1 案例

  • 编程实现People类的封装,特征有:姓名、年龄、国际,要求提供打印所有特征的方法。
  • 编程实现PeopleTest类,main方法中使用有参方式构造两个对象并打印

1.2 基本概念

  • 使用static关键字修饰成员变量表示的静态含义,此时成员变量由对象层级提升类层级,也就是整个类只有一份并被所有对象共享,该成员变量随着类的加载准备就绪,与是否创建对象无关
  • static关键字修饰的成员变量可以使用引用.的方式访问,推荐类名.的方式。

1.3 使用方式

  • 在非静态成员方法中既能访问非静态成员又能访问静态成员。(成员:成员变量+成员方法,静态成员被所有对象共享)
  • 在静态成员方法中只能访问静态成员不能访问非静态成员。(成员:成员变量+成员方法,因此此时可能还没有创建对象)
  • 在此以后的开发中只有隶属于类层级并被所有对象共享的内容才可以使用static关键字修饰。(不能滥用static关键字)

1.4 构造块和静态代码块

  • 构造块:在类体中直接使用{}括起来的代码块。
  • 每创建一个对象都会执行一次代码块。
  • 静态的代码块:使用statis关键字修饰构造块。
  • 静态代码块随着类的加载时,执行一次

1.5 又见main方法

  • 语法格式:public static void main(String[] args){}

1.6 编程实现Sigleton类封装

实现singleton类的测试,要求main方法中能且得到该类的一个对象
image.png
image.png

1.7 单例设计模式概念

  • 在某些特殊场合,一个类对外提供有且一个对象时,这样的类叫做单例类,而设计单例流程和思想叫做单例设计模式。

1.8 单例设计模式的实现流程

  • 私有构造方法,使用private关键字修饰。
  • 声明本类型的引用指向本类类型的对象,并使用private statis关键字修饰
  • 提供公有的get方法负责把对象返回出去,并使用public statis 关键字共同修饰。

1.9 单例设计模式的实现方式

  • 单例设计模式的实现方式有两种:饿汉式和懒汉式,在以后的开发中推荐饿汉式。

image.png

2 继承

2.1 继承的概念

  • 当多个类之间有相同的特征和行为时,可以将相同的内容提取出来组成一个公共类,让多个类吸收公共类已有的特征和行为而在多个类型只需要编写自己独有特征和行为的机制,叫做继承。

  • 在Java语言中使用extends(拓展)关键字来表示继承的关系

  • e.g. :

public class Work extends Persons{} -表示Wor类继承Persons类
其中Persons类叫做超类、父类、基类
其中Work类叫做派生类、子类、孩子类

  • 使用继承提高代码的复用性,可维护及扩展性,是多态的前提条件

2.2 继承的特点

  • 子类不能继承父类的构造方法和私有方法,但是私有成员变量可以被继承,只是不能访问
  • 无论使用什么方式创建的子类对象都会自动的调用父类的无参数构造方法,来初始化从父类中继承的成员变量,相当于在构造方法的第一行增加代码super()的效果
  • 使用继承必须瞒住逻辑关系:子类 is a 父类,但是不能滥用继承
  • java语言中只支持单继承不支持多继承,也就是说一个子类只能有一个父类但是一个父类可以有多个子类

2.3 方法重写的概念

  • 从父类中继承下来的方法不满足子类的需求时候,就需要在子类中重写一个和父类方法一样的方法覆盖从父类中继承下来的版本,该方法就是方法的重写(override)

2.4 方法重写的原则

  • 要求方法名字相同、参数列表相同以及返回值类型相同,从java5开始允许返回子类类型
  • 要求方法的访问权限不能变小,可以相同或者变大
  • 要求方法不能抛出跟大的异常(异常机制)

2.5 继承案例

image.png
image.png
image.png
image.png

2.6 又见构造块与静态代码块(笔试经典)

  • 先执行父类的静态代码块,在执行子类的静态代码块
  • 执行父类的构造块,执行父类的构造方法
  • 执行子类的构造块,执行子类的构造方法

3 访问的控制

3.1 常用的访问控制符

image.png
注意事项

  • public修饰的成员可以在任意位置使用
  • private修饰的成员只能在本类中使用
  • 通常情况下,成员方法都使用public关键字修饰,成员变量都是使用private关键字修饰

3.2 package语句的由来

  • 定义类时需要指定类的名称,但是如果仅仅将类名作为类的唯一标识,则不可避免的出现命名冲突的问题。这会给组件复用以及团队间的合作造成很大的麻烦
  • 在java语言中,用包(package)的概念就是解决 命名冲突的问题。

3.3 包的定义

  • 在定义一个类时,除了定义类的名称一般还要指定包名,格式如下:

package 包名;
package 包名1.包名2.包名3…..包名n;

  • 为了实现项目管理、解决命名冲突以及权限控制的效果。

3.4 定义包的规范

  • 如果各个公司或开发组织的程序员都随心所欲的命名包名的话,仍然不能从根本上解决命名冲突的问题。因此,在指定包名的时候应该按照一定的规范。
  • org.apache.commons.lang.StringUtil
  • 其中StringUtils是类名而org.apache.commons.lang是多层包名, 其含义如下: org.apache表示公司或组织的信息(是这个公司(或组织)域名的反写) ; common表示项目的名称信息; lang表示模块的名称信息。

3.5 包的导入

  • 使用import关键字导入包
  • 使用import关键字导入静态成员,从java5开始支持

4 final关键字(重点)

4.1 基本概念

  • final本意为”最终的、不可改变的”,可以修饰类、成员方法以及成员变量

4.2 使用方式

  • final关键字修饰类的体现在该类不能被继承

-主要用于防止滥用继承,如:java.long.String类等

  • final关键字修饰成员变量方法体现在该方法不能被重写但是可以被继承

-主要是为了防止不经意间造成重写,如:java.text.Dateformat类中format方法等

  • final关键字修饰成员变量体现在该变量必须初始化切不能改变

-主要用于防止不经意间造成改变,如java.long.Thread类中max_PRIORITY

4.3 常量的概念

  • 在以后的开发中很少单独使用final关键字来修饰成员变量,通常使用public statis final关键字共同修饰成员变量来表达常量的含义,常量的命名规范要求所有的字母都要大写,但是不同单词之间采用下划线连。
  • public static final double PI=3.14;

四、 多态和特殊类

1. 多态

1.1 多态的概念

  • 多态指同一事物表现出的多种形态

1.2 多态的语法格式

  • 父类类型 引用变量名 = new 子类类型
  • e.g. :

Shape sr = new Rect();
sr.show();

1.3 案例题目

image.png
image.png
image.png
image.png

1.4 多态的特点

  • 当父类类型的引用指向子类类型的对象时,父类类型的引用直接调用父类独有的方法。
  • 当父类类型的引用指向子类类型对象时,父类类型引用不可以直接调用子类的独有方法
  • 对于父子类都有的非静态方法,编译阶段调用父类版本,运行阶段调用子类重新的版本(动态绑定)
  • 对于父子类都有的静态方法来说,编译和运行阶段都是调用父类版本

1.5 引用数据类型之间的转换

  • 引用数据类型的转换有两种:自动类型转换和强制类型转换
  • 自动类型转换指小类型向大类型转换,也就是子类向父类转换,也就是向上转型
  • 强制类型转换指大类型向小类型转换,也就是父类转向子类,就是向下转型或者显式类型转换
  • 引用数据类型之间的转换必须发生在父子类之间,否则编译报错

  • 若强制的目标类型并不是该引用真正指向的数据类型时,则编译通过,运行阶段发生类型转换异常

  • 为了避免上述的错误发生,应该在强转之前就判断,格式如下:

if(引用变量instanceof数据类型)
判断引用变量指向的对象是否为后面的数据类型

1.6 多态的实际意义

  • 多态的实际意义在于屏蔽不同子类的差异性实现通用编程带来不同的效果

2 抽象类

2.1 抽象方法的概念

  • 抽象方法主要指不能具体实现的方法并且使用abstract关键词修饰,也就是没有方法体
  • 具体格式如下

访问权限abstract 返回值类型 方法名(形参列表);
public abstract void cry();

2.2 抽象类的概念

  • 抽象类指不能具体实例化并且使用abstract关键字修饰,也就是不能创建对象

2.3 抽象类和抽象方法的关系

  • 抽象类中可以有成员方法、构造方法、成员变量
  • 抽象类中可以没有抽象方法,也可以有抽象方法
  • 拥有抽象方法的类必须是抽象类,因此真正意义上的抽象类应该是具有抽象方法并且使用abstract修饰的类

2.4 抽象类的实际意义

  • 抽象类的实际意义不在于创建对象而在于被继承
  • 当一个类继承抽象类后必须重写抽象方法,否则该类就会变成抽象类,也就是抽象类对子类具有强制性和规范性,因此叫做模板设计模式

2.5 开发经验

  • 在以后的开发中推荐使用多态的格式,此时父类类型引用直接调用所有方法一定是父类拥有的方法,若以后更换子类时,只需要将new关键字后面的子类类型修改而其他地方无需改变就可以立即生效,从未提高了代码的可维护性和拓展性
  • 该方法的缺点就是:父类引用不能直接调用子类独有的方法,若是调用则需要强制类型装换

2.6 抽象类的应用

  • 银行有定期账户和活期账户。继承自账户类。账户类:
  • public class Account{

private double money;
public double getLixi(){}
}

3 接口

3.1 接口的基本概念

  • 接口就是比抽象类更加抽象的类,体现就在所有的方法都是抽象方法
  • 定义类的关键字是class ,而定义接口的关键字是interface

3.2 接口项目

image.png
image.png
image.png
image.png

3.3 接口和类之间的关系

image.png

3.4 抽象类和接口的主要区别(笔试题)

  • 定义抽象类的关键字是abstract class ,而定义接口的关键字是interface
  • 继承抽象类的关键字是extends,而实现接口的关键字是implement
  • 继续抽象类支出单继承 , 而实现接口支持多实现
  • 抽象类中可以有构造方法,而接口中不能有构造方法
  • 抽象类中可以有成员变量,而接口只可以有常量

3.5 抽象类和接口的主要区别

  • 抽象类可以有成员方法,而接口只可以有抽象方法
  • 抽象类中增加方法时子类不用重写,而接口中增加方法时实现类需要重写(java8以前的版本)
  • 从java8开始增加新特性,接口允许出现非抽象方法和静态方法,但是非抽象方法需要使用default关键字修饰,从java9开始增加新特性,接口允许出现私有方法

五、 特殊类

1 内部类

1.1 内部类的基本概念

  • 当一个类的定义出现在另一个类的类体中时,那么这个类叫做内部类(Inner),而这个内部类所在的类叫做外部类(Outer)
  • 类中的内容:成员变量、成员方法、构造方法、静态成员、构造块和静态代码块、内部类

1.2 实际作用

  • 当一个类存在价值是为了某个类单独服务时,那么就可以将这个类定义为所有服务类的内部类,这样可以隐藏该类的实现细节可以方便的访问外部类的私有成员而不再需要提供公有的get和set方法

1.3 内部类的分类

  • 普通内部类 将定义一个类的定义放在另一个类的类体中
  • 静态内部类 使用static关键字修饰的内部类,隶属于类层级
  • 局部内部类 直接一个类的定义放在方法体的内部时
  • 匿名内部类 就是指没有名字的内部类

1.4 普通(成员) 内部类的格式

  • 访问修饰符号cladd外部类的类名{

访问修饰符class 内部类的类名{
内部类的类体;
}
}

1.5 普通内部类的使用方式

  • 普通的内部类和普通的类一样可以定义成员变量、成员方法和构造方法等
  • 普通内部类和普通类一样可以使用final或者abstract关键字修饰
  • 普通内部类还可以使用private或者protected关键字修饰
  • 普通内部类需要使用外部类的对象来创建对象
  • 如果内部类访问外部类中与本类内部同名的成员变量或方法时,需要使用this关键字

1.6 静态内部类的格式

  • 访问修饰符class外部类的类名{

访问修饰符static class 内部类的类名{
内部类的类体;
}
}

1.7 静态内部类的使用方式

  • 静态内部类不能直接访问外部类的非静态成员
  • 静态内部类可以直接创建对象
  • 如果静态内部类访问外部类中与本类内同名的成员变量或方法时,需要使用类名.的方式访问

1.8 局部(方法)内部类的格式

  • 访问修饰符class外部类的类名{

访问修饰符 返回值类型 成员方法名(形参列表){
class 内部类的类名{
内部类的类体;
}
}
}

1.9 局部内部类的使用方式

  • 局部内部类只能在该方法的内部使用
  • 局部内部类可以在方法体内部直接创建对象
  • 局部内部类不能直接访问控制符和static关键字修饰符
  • 局部内部类可以使用外部方法的局部变量,但是必须是final的。由局部内部类和局部变量的声明周期不同所致

1.10 回调模式的概念

  • 回调模式是指 如果一个方法的参数类型是接口类型,则在调用该方法时需要创建并传递一个实现此接口类型的对象;而该方法在运行时会调用到参数对象中所实现的方法(接口中定义的)

1.11 开发分享

  • 当接口/类类型的引用作为方法的形参时,实参的传递方式两种
  • 自定义类实现接口/继承类并重写方法,然后创建该类对象作为实参传递
  • 使用上述匿名内部类的语法格式得是接口/类类型的引用即可

1.12 匿名内部类的语法格式

  • 接口/父类类型 引用变量名 = new 接口/父类类型(){方法的重写};

2 枚举

2.1 枚举的基本概念

  • 在日常生活中这些事务的取值只有明确的几个固定值,此时描述这些事物的所有值都是可以 —列举出来,而这个列举出来的类型就叫枚举类型

2.2 枚举的定义

  • 使用public static final 表示的常量描述较为繁琐 , 使用enum关键字来定义枚举类型取代常量,枚举类型是从java开始增加的一种引用数据类型
  • 枚举值就是当前类的类型,也就是指向本类的对象,默认使用public static final关键字共同修饰,因此采用枚举类型.的方式调用
  • 枚举类可以定义构造方法,但是构造方法的修饰符必须是private,默认也是私有。

2.3 Enum类的概念和方法

  • 所有的枚举类都是继承java.long.Enum类,常用方法如下:

image.png

2.4 枚举类实现接口的方式

  • 枚举类实现接口后需要重写抽象方法,而重写方法的方式两种:重写一个,或者每个对象都是重写。

3 注解

3.1 注解的基本概念

  • 注解又是标注,是从java5开始增加的一种引用数据类型。
  • 注解本质上就是代码中特殊标记,通过这些标记可以在编译、类加载、以及运行时执行指定的处理。

3.2 注解的语法格式

  • 访问修饰符@interface注解名称{

注解成员;
}

  • 自定义注解自动继承java.long.annotation.Annotation接口。
  • 通过@注解名称的方式可以修饰包、类、成员方法、构造方法、参数、局部变量的声明等。

3.3 注解的使用

  • 注解中只有成员变量没有成员方法,而注解成员变量以”无形参的方法”形式来声明,其方法名定义了该成员变量的名字,其返回值定义了该成员变量的类型。
  • 如果注解只有一个参数成员,建议使用名为value,而类型只能八种基本数据类型、String类型、Class类型、enum类型及Annotation类型

3.4 元注解的概念

  • 元注解是可以注解到注解的注解,或者说元注解是一种基本注解,但是它能够应用到其他的注解上面
  • 元注解主要有@Retention、@Documented 、@Taget 、@Inherited 、@Repeatable

3.5 元注解@Retention

  • Retention 应用到一个注解上用于说明该注解的生命周期,取值如下:
  • RetentionPolicy.SOURCE注解只在源码阶段保留,在编译器进行编译时它将被忽视
  • RetentionPolicy.CLASS 注解只被保留到编译进行的时候,它并不会被加载jvm中,默认方法
  • RetentionPolicy.RUNTIME注解可以保留到程序运行的时候,它会被加载进入jvm中,所以在程序运行时可以获取它们

3.6 元注解@Documented

  • 使用javadoc工具可以从程序源代码中抽取类、方法、成员等注释形成一个和源代码配套额API帮助文档,而该该工具抽取时默认不包括注解内容。
  • @Documented用于指定该注解将被javadoc工具提取成文档
  • 定义为@Documented的注解必修设置Retention 值为RUNTIME。

3.7 元注解@Taget

  • @Taget用于指定被修饰的注解用于哪些元素修饰,取值如下:

image.png

3.8 元注解@Inherrited

  • @Inherited并不是说注解本身可以继承,而是说如果一个超类被该注解标记过的注解进行注解时,如果子类没有被任何注解应用时,则子类就继承超类的注解。

3.9 元注解@Repeatable

  • @Repeatable表示自然可重复的含义,从java8开始在增加的新特性
  • 从java8开始对元注解@Target的参数类型ElementType枚举增加俩两个
  • 其中ElementType.TYPE_PARAMETER表示该注解能写在类型变量的声明语句中,如:泛型
  • 其中ElementType.TYPE_USE表示该注解能写在使用类型的任何语句中

3.10 常见的预制注解

  • 预制注解就是Java语言自身提供的注解,具体如下:

image.png

  • 常见的预制注解如下:

image.png


2

ar
r内存结构之栈区

内存结构之栈区

内存结构之栈区

内存结构之栈区

内存结构之栈区

内存结构之栈区

内存结构之栈区

第十一章:常用类的概述和用

11.1 常用的包(熟悉)

11.1.1 包的名称和功能

java.lang包 - 该包是Java语言的核心包,并且该包中的所有内容由Java虚拟机自动导入。 如:System类、String类、…
java.util包 - 该包是Java语言的工具包,里面提供了大量工具类以及集合类等。 如:Scanner类、Random类、List集合、…
java.io包 - 该包是Java语言中的输入输出包,里面提供了大量读写文件相关的类等。 如:FileInputStream类、FileOutputStream类、…
java.net包 - 该包是Java语言中的网络包,里面提供了大量网络编程相关的类等。 如:ServerSocket类、Socket类、…
java.sql 包 - 该包是Java语言中的数据包,里面提供了大量操作数据库的类和接口等。 如:DriverManager类、Connection接口、…
Java程序员在编程时可以使用大量类库,因此Java编程时需要记的很多,对编程能力本身要求不是 特别的高。

11.2 Object类的概述(重点)

11.2.1 基本概念

java.lang.Object类是Java语言中类层次结构的根类,也就是说任何一个类都是该类的直接或者间 接子类。
如果定义一个Java类时没有使用extends关键字声明其父类,则其父类为 java.lang.Object 类。Object类定义了“对象”的基本行为, 被子类默认继承。

11.2.2 常用的方法

image.png

案例题目:编程实现Student类的封装,特征:学号(id)和姓名,要求提供打印所有特征的方法。 编程实现StudentTest类,在main方法中使用有参方式构造两个Student类型的对象并打印特征。
题目扩展**:**如何实现以姓名作为基准判断两个对象是否相等?以及以学号和姓名同时作为基准判断两个对象是否相等?
Student.java
StudentTest.java

11.3 包装类(熟悉)

11.3.1 包装类的概念

通常情况下基本数据类型的变量不是对象,为了满足万物皆对象的理念就需要对基本数据类型的变 量进行打包封装处理变成对象,而负责将这些变量声明为成员变量进行对象化处理的相关类,叫做包装类。
如:
Person p = new Person();
int num = 10;

11.3.2 包装类的分类

image.png

11.3.3 Integer类的概述

(1)基本概念

java.lang.Integer类内部包装了一个int类型的变量作为成员变量,主要用于实现对int类型的包装并 提供int类型到String类之间的转换等方法。

(2)常用的常量

image.png

(3)常用的方法

image.png

(4)装箱和拆箱的概念

  1. Java5发布之前使用包装类对象进行运算时,需要较为繁琐的“拆箱”和“装箱”操作;即运算前先将 包装类对象拆分为基本类型数据,运算后再将结果封装成包装类对象。<br /> Java5开始增加了自动拆箱和自动装箱的功能。

(5)自动装箱池

在Integer类的内部提供了自动装箱池技术,将-128到127之间的整数已经装箱完毕,当程序中使用 该范围之间的整数时,无需装箱直接取用自动装箱池中的对象即可,从而提高效率。

11.3.4 Double类的概述

(1)基本概念

java.lang.Double类型内部包装了一个double类型的变量作为成员变量,主要用于实现对double 类型的包装并提供double类型到String类之间的转换等方法。

(2)常用的常量

image.png

(3)常用的方法

image.png

扩展: java.lang.Number类是个抽象类,是上述类的父类来描述所有类共有的成员。

11.3.5 Boolean类的概述

(1)基本概念

java.lang.Boolean类型内部包装了一个boolean类型的变量作为成员变量,主要用于实现对 boolean类型的包装并提供boolean类型到String类之间的转换等方法。

(2)常用的常量

image.png

(3)常用的方法

image.png

11.3.6 Character类的概述

(1)基本概念

java.lang.Character类型内部包装了一个char类型的变量作为成员变量,主要用于实现对char类型的包装并提供字符类别的判断和转换等方法。

(2)常用的常量

image.png

(3)常用的方法

image.png

11.3.7 包装类(Wrapper)的使用总结

  • 基本数据类型转换为对应包装类的方式

调用包装类的构造方法或静态方法即可

  • 获取包装类对象中基本数据类型变量数值的方式

调用包装类中的xxxValue方法即可

  • 字符串转换为基本数据类型的方式

调用包装类中的parseXxx方法即可

11.4 数学处理类(熟悉)

11.4.1 Math类的概述

(1)基本概念

java.lang.Math类主要用于提供执行数学运算的方法,如:对数,平方根。

(2)常用的方法
image.png

11.4.2 BigDecimal类的概述

(1)基本概念

  1. 由于float类型和double类型在运算时可能会有误差,若希望实现精确运算则借助<br />java.math.BigDecimal类型加以描述。

(2)常用的方法

image.png

11.4.3 BigInteger类的概念

(1)基本概念

若希望表示比long类型范围还大的整数数据,则需要借助java.math.BigInteger类型描述。

(2)常用的方法

image.png

第十二章 String类的概述和使用

12.1 String类的概念(重点)

  • java.lang.String类用于描述字符串,Java程序中所有的字符串字面值都可以使用该类的对象加以描 述,如:”abc”。
  • 该类由final关键字修饰,表示该类不能被继承。 从jdk1.9开始该类的底层不使用char[]来存储数据,而是改成 byte[]加上编码标记,从而节约了一 些空间。
  • 该类描述的字符串内容是个常量不可更改,因此可以被共享使用。 如:

String str1 = “abc”; - 其中”abc”这个字符串是个常量不可改变。
str1 = “123”;
- 将“123”字符串的地址赋值给变量str1。
- 改变str1的指向并没有改变指向的内容

12.2 常量池的概念(原理)

由于String类型描述的字符串内容是常量不可改变,因此Java虚拟机将首次出现的字符串放入常量 池中,若后续代码中出现了相同字符串内容则直接使用池中已有的字符串对象而无需申请内存及创建对 象,从而提高了性能。

12.3 常用的构造方法(练熟、记住)

image.png

12.4 常用的成员方法(练熟、记住)

image.png

  • 案例 判断字符串“上海自来水来自海上”是否为回文并打印,所谓回文是指一个字符序列无论从左向右读 还是从右向左读都是相同的句子。

image.png
image.png

  • 案例题目 编程实现字符串之间大小的比较并打印。

image.png
image.png

  • 案例题目 编程实现上述方法的使用。

image.png
image.png

  • 案例 提示用户从键盘输入用户名和密码信息,若输入”admin”和”123456”则提示“登录成功,欢迎使 用”,否则提示“用户名或密码错误,您还有n次机会”,若用户输入三次后依然错误则提示“账户已 冻结,请联系客服人员!”

image.png

image.png

  • 案例 编写通用的代码可以查询字符串”Good Good Study, Day Day Up!”中所有”Day”出现的索引位置并 打印出来。

StringIndexTest.java

image.png

  • 案例 提示用户从键盘输入一个字符串和一个字符,输出该字符(不含)后面的所有子字符串。

image.png

12.5 正则表达式的概念(了解)

正则表达式本质就是一个“规则字符串”,可以用于对字符串数据的格式进行验证,以及匹配、查 找、替换等操作。该字符串通常使用^运算符作为开头标志,使用$运算符作为结尾标志,当然也可以省 略。

12.6 正则表达式的规则(了解)

image.png

12.7 正则表达式相关的方法(熟悉)

image.png

  • 案例题目

使用正则表达式描述一下银行卡密码的规则:要求是由6位数字组成。
使用正则表达式描述一下QQ号码的规则:要求是由非0开头的5~15位数组成。
使用正则表达式描述一下手机号码的规则:要求是由1开头,第二位数是3、4、5、7、8中的一 位,总共11位
描述身份证号码的规则:总共18位,6位数字代表地区,4位数字代表年,2位数字代表月,2位数 字代表日期, 3位数字代表个人,最后一位可能数字也可能是X。
image.png

image.png
image.png

第十三章 可变字符串类和日期相关类

13.1 可变字符串类(重点)

13.1.1 基本概念

由于String类描述的字符串内容是个常量不可改变,当需要在Java代码中描述大量类似的字符串 时,只能单独申请和存储,此时会造成内存空间的浪费。 为了解决上述问题,可以使用java.lang.StringBuilder类和java.lang.StringBuffer类来描述字符序 列可以改变的字符串,如:”ab”。StringBuffer类是从jdk1.0开始存在,属于线程安全的类,因此效率比较低。StringBuilder类是从jdk1.5开始存在,属于非线程安全的类,效率比较高。

13.1.2 StringBuilder类常用的构造方法

截屏2021-06-04 下午8.29.32.png

13.1.3 StringBuilder类常用的成员方法

image.png

  • 注意

    作为参数传递的话,方法内部String不会改变其值,StringBuffer和StringBuilder会改变其值。

13.1.4 返回值的设计

  • StringBuilder的很多方法的返回值均为StringBuilder类型。这些方法的返回语句均为:return this。
  • 由此可见,这些方法在对StringBuilder所封装的字符序列进行改变后又返回了该对象的引用。基 于这样设计的目的在于可以连续调用。

13.2 Java8之前的日期相关类(熟悉)

13.2.1 System类的概述

(1)基本概念

Java.lang.System类中提供了一些有用的类字段和方法。

(2)常用的方法

image.png

13.2.2 Date类的概述

(1)基本概念

  • java.util.Date类主要用于描述特定的瞬间,也就是年月日时分秒,可以精确到毫秒。

    (2)常用的方法

    image.png

    13.2.3 SimpleDateFormat类的概述

    (1)基本概念

  • java.text.SimpleDateFormat类主要用于实现日期和文本之间的转换。

    (2)常用的方法

    image.png

    13.2.4 Calendar类的概述

    (1)基本概念

    java.util.Calender类主要用于描述特定的瞬间,取代Date类中的过时方法实现全球化。 该类是个抽象类,因此不能实例化对象,其具体子类针对不同国家的日历系统,其中应用最广泛的 是GregorianCalendar(格里高利历),对应世界上绝大多数国家/地区使用的标准日历系统。

    (2)常用的方法

    image.png

    (3)多态的使用场合

  • 通过方法的参数传递形成多态;

public static void draw(Shape s){ s.show();
}
draw(new Rect(1, 2, 3, 4));

  • 在方法体中直接使用多态的语法格式

Account acc = new FixedAccount();

  • 通过方法的返回值类型形成多态

Calender getInstance(){
return new GregorianCalendar(zone, aLocale);
}

13.3 Java8中的日期相关类(熟悉)

13.3.1 Java8日期类的由来

JDK 1.0中包含了一个java.util.Date类,但是它的大多数方法已经在JDK 1.1引入Calendar类之后被弃用 了。而Calendar并不比Date好多少。它们面临的问题是:

  • Date类中的年份是从1900开始的,而月份都从0开始。
  • 格式化只对Date类有用,对Calendar类则不能使用。
  • 非线程安全等。

    13.3.2 Java8日期类的概述

  • Java 8通过发布新的Date-Time API来进一步加强对 日期与时间的处理。

  • java.time包:该包日期/时间API的基础包。
  • java.time.chrono包:该包提供对不同日历系统的访问。
  • java.time.format包:该包能够格式化和解析日期时间对象。
  • java.time.temporal包:该包包含底层框架和扩展特性。
  • java.time.zone包:该包支持不同时区以及相关规则的类。

    13.3.3 LocalDate类的概述

    (1)基本概念

  • java.time.LocalDate类主要用于描述年-月-日格式的日期信息,该类不表示时间和时区信息。

    (2)常用的方法

    image.png

    13.3.4 LocalTime类的概述

    (1)基本概念

    java.time.LocalTime 类主要用于描述时间信息,可以描述时分秒以及纳秒。

    (2)常用的方法

    image.png

    13.3.5 LocalDateTime类的概述

    (1)基本概念

  • java.time.LocalDateTime类主要用于描述ISO-8601日历系统中没有时区的日期时间,如2007-12- 03T10:15:30。

    (2)常用的方法

    image.png

    13.3.6 Instant类的概述

    (1)基本概念

  • java.time.Instant类主要用于描述瞬间的时间点信息。

    (2)常用的方法

    image.png

    13.3.7 DateTimeFormatter类的概述

    (1)基本概念

  • java.time.format.DateTimeFormatter类主要用于格式化和解析日期。

    (2)常用的方法

    image.png

第十四章 集合类库(上)

14.1 集合的概述(重点)

14.1.1 集合的由来

  • 当需要在Java程序中记录单个数据内容时,则声明一个变量。
  • 当需要在Java程序中记录多个类型相同的数据内容时,声明一个一维数组。
  • 当需要在Java程序中记录多个类型不同的数据内容时,则创建一个对象。
  • 当需要在Java程序中记录多个类型相同的对象数据时,创建一个对象数组。
  • 当需要在Java程序中记录多个类型不同的对象数据时,则准备一个集合。

    14.1.2 集合的框架结构

  • Java中集合框架顶层框架是:java.util.Collection集合 和 java.util.Map集合。

  • 其中Collection集合中存取元素的基本单位是:单个元素。
  • 其中Map集合中存取元素的基本单位是:单对元素。

    14.2 Collection集合(重点)

    14.2.1 基本概念

  • java.util.Collection接口是List接口、Queue 接口以及Set接口的父接口,因此该接口里定义的方法 既可用于操作List集合,也可用于操作Queue集合和Set集合。

    14.2.1 常用的方法(练熟、记住)

    image.png

    14.3 Iterator接口(重点)

    14.3.1 基本概念

  • java.util.Iterator接口主要用于描述迭代器对象,可以遍历Collection集合中的所有元素。

  • java.util.Collection接口继承Iterator接口,因此所有实现Collection接口的实现类都可以使用该迭 代器对象。

    14.3.2 常用的方法

    image.png
    案例题目: 如何使用迭代器实现toString方法的打印效果?
    CollectionPrintTest.java

    14.4 for each循环(重点)

    14.4.1 基本概念

  • Java5推出了增强型for循环语句,可以应用数组和集合的遍历。

  • 是经典迭代的“简化版”。

    14.4.2 语法格式

  • for(元素类型 变量名 : 数组/集合名称) {

    循环体;
    }

    14.4.3 执行流程

  • 不断地从数组/集合中取出一个元素赋值给变量名并执行循环体,直到取完所有元素为止。

    14.5 List集合(重中之重)

    14.5.1 基本概念

  • java.util.List集合是Collection集合的子集合,该集合中允许有重复的元素并且有先后放入次序。

  • 该集合的主要实现类有:ArrayList类、LinkedList类、Stack类、Vector类。
  • 其中ArrayList类的底层是采用动态数组进行数据管理的,支持下标访问,增删元素不方便。
  • 其中LinkedList类的底层是采用双向链表进行数据管理的,访问不方便,增删元素方便。
  • 可以认为ArrayList和LinkedList的方法在逻辑上完全一样,只是在性能上有一定的差别,ArrayList 更适合于随机访问而LinkedList更适合于插入和删除;在性能要求不是特别苛刻的情形下可以忽略这个差别。
  • 其中Stack类的底层是采用动态数组进行数据管理的,该类主要用于描述一种具有后进先出特征的数据结构,叫做栈(last in first out LIFO)。
  • 其中Vector类的底层是采用动态数组进行数据管理的,该类与ArrayList类相比属于线程安全的类,效率比较低,以后开发中基本不用。

    14.5.2 常用的方法

    image.png

    案例题目

    准备一个Stack集合,将数据11、22、33、44、55依次入栈并打印,然后查看栈顶元素并打印, 然后将栈中所有数据依次出栈并打印。
    再准备一个Stack对象,将数据从第一个栈中取出来放入第二个栈中,然后再从第二个栈中取出并 打印。
    image.png

14.6 Queue集合(重点)

14.6.1 基本概念

  • java.util.Queue集合是Collection集合的子集合,与List集合属于平级关系。
  • 该集合的主要用于描述具有先进先出特征的数据结构,叫做队列(first in first out FIFO)。
  • 该集合的主要实现类是LinkedList类,因为该类在增删方面比较有优势。

    14.6.2 常用的方法

    image.png

    案例题目

    准备一个Queue集合,将数据11、22、33、44、55依次入队并打印,然后查看队首元素并打印, 然后将队列中所有数据依次出队并打印。
    image.png

第十五章 集合类库(下)

15.1 泛型机制(熟悉)

15.1.1 基本概念

  • 通常情况下集合中可以存放不同类型的对象,是因为将所有对象都看做Object类型放入的,因此 从集合中取出元素时也是Object类型,为了表达该元素真实的数据类型,则需要强制类型转换, 而强制类型转换可能会引发类型转换异常。
  • 为了避免上述错误的发生,从Java5开始增加泛型机制,也就是在集合名称的右侧使用<数据类型> 的方式来明确要求该集合中可以存放的元素类型,若放入其它类型的元素则编译报错。
  • 泛型只在编译时期有效,在运行时期不区分是什么类型。

    15.1.2 底层原理

  • 泛型的本质就是参数化类型,也就是让数据类型作为参数传递,其中E相当于形式参数负责占位, 而使用集合时<>中的数据类型相当于实际参数,用于给形式参数E进行初始化,从而使得集合中所 有的E被实际参数替换,由于实际参数可以传递各种各样广泛的数据类型,因此得名为泛型。

  • 如:

image.png

15.1.3 自定义泛型接口

  • 泛型接口和普通接口的区别就是后面添加了类型参数列表,可以有多个类型参数,如:等。

    15.1.4 自定义泛型类

  • 泛型类和普通类的区别就是类名后面添加了类型参数列表,可以有多个类型参数,如: 等。

  • 实例化泛型类时应该指定具体的数据类型,并且是引用数据类型而不是基本数据类型。
  • 父类有泛型,子类可以选择保留泛型也可以选择指定泛型类型。 子类必须是“富二代”,
  • 子类除了指定或保留父类的泛型,还可以增加自己的泛型。

    15.1.5 自定义泛型方法

  • 泛型方法就是我们输入参数的时候,输入的是泛型参数,而不是具体的参数。我们在调用这个泛型 方法的时需要对泛型参数进行实例化。

  • 泛型方法的格式:

    [访问权限] <泛型> 返回值类型 方法名([泛型标识 参数名称]) { 方法体; }

  • 在静态方法中使用泛型参数的时候,需要我们把静态方法定义为泛型方法。

    15.1.6 泛型在继承上的体现

  • 如果B是A的一个子类或子接口,而G是具有泛型声明的类或接口,则G并不是G的子类型!

比如:String是Object的子类,但是List并不是List的子类。

15.1.7 通配符的使用

  • 有时候我们希望传入的类型在一个指定的范围内,此时就可以使用泛型通配符了。
  • 如:之前传入的类型要求为Integer类型,但是后来业务需要Integer的父类Number类也可以传 入。
  • 泛型中有三种通配符形式:

    <?> 无限制通配符:表示我们可以传入任意类型的参数。
    <? extends E> 表示类型的上界是E,只能是E或者是E的子类。
    <? super E> 表示类型的下界是E,只能是E或者是E的父类。

    15.2 Set集合(熟悉)

    15.2.1 基本概念

  • java.util.Set集合是Collection集合的子集合,与List集合平级。

  • 该集合中元素没有先后放入次序,且不允许重复。
  • 该集合的主要实现类是:HashSet类 和 TreeSet类以及LinkedHashSet类。
  • 其中HashSet类的底层是采用哈希表进行数据管理的。
  • 其中TreeSet类的底层是采用红黑树进行数据管理的。
  • 其中LinkedHashSet类与HashSet类的不同之处在于内部维护了一个双向链表,链表中记录了元 素的迭代顺序,也就是元素插入集合中的先后顺序,因此便于迭代。

    15.2.2 常用的方法

  • 参考Collection集合中的方法即可!

  • 案例题目

准备一个Set集合指向HashSet对象,向该集合中添加元素”two”并打印,再向集合中添加元 素”one”并打印,再向集合中添加元素”three”并打印,再向集合中添加”one”并打印。
image.png

15.2.3 元素放入HashSet集合的原理

  • 使用元素调用hashCode方法获取对应的哈希码值,再由某种哈希算法计算出该元素在数组中的索引位置。
  • 若该位置没有元素,则将该元素直接放入即可。
  • 若该位置有元素,则使用新元素与已有元素依次比较哈希值,若哈希值不相同,则将该元素直接放入。
  • 若新元素与已有元素的哈希值相同,则使用新元素调用equals方法与已有元素依次比较。
  • 若相等则添加元素失败,否则将元素直接放入即可。

  • 思考:为什么要求重写equals方法后要重写hashCode方法呢?

  • 解析: 当两个元素调用equals方法相等时证明这两个元素相同,重写hashCode方法后保证这两个元素得到的哈希码值相同,由同一个哈希算法生成的索引位置相同,此时只需要与该索引位置已有元 素比较即可,从而提高效率并避免重复元素的出现。

    15.2.5 TreeSet集合的概念

  • 二叉树主要指每个节点最多只有两个子节点的树形结构。

  • 满足以下3个特征的二叉树叫做有序二叉树。

a.左子树中的任意节点元素都小于根节点元素值;
b.右子树中的任意节点元素都大于根节点元素值;
c.左子树和右子树的内部也遵守上述规则;

  • 由于TreeSet集合的底层采用红黑树进行数据的管理,当有新元素插入到TreeSet集合时,需要使 用新元素与集合中已有的元素依次比较来确定新元素的合理位置。
  • 比较元素大小的规则有两种方式:

使用元素的自然排序规则进行比较并排序,让元素类型实现java.lang.Comparable接口; 使用比较器规则进行比较并排序,构造TreeSet集合时传入java.util.Comparator接口;

  • 自然排序的规则比较单一,而比较器的规则比较多元化,而且比较器优先于自然排序;

    15.3 Map集合(重点)

    15.3.1 基本概念

  • java.util.Map集合中存取元素的基本单位是:单对元素,其中类型参数如下:

K - 此映射所维护的键(Key)的类型,相当于目录。
V - 映射值(Value)的类型,相当于内容。

  • 该集合中key是不允许重复的,而且一个key只能对应一个value。 该集合的主要实现类有:HashMap类、TreeMap类、LinkedHashMap类、Hashtable类、 Properties类。
  • 其中HashMap类的底层是采用哈希表进行数据管理的。
  • 其中TreeMap类的底层是采用红黑树进行数据管理的。
  • 其中LinkedHashMap类与HashMap类的不同之处在于内部维护了一个双向链表,链表中记录了 元素的迭代顺序,也就是元素插入集合中的先后顺序,因此便于迭代。
  • 其中Hashtable类是古老的Map实现类,与HashMap类相比属于线程安全的类,且不允许null作 为key或者value的数值。
  • 其中Properties类是Hashtable类的子类,该对象用于处理属性文件,key和value都是String类 型的。
  • Map集合是面向查询优化的数据结构, 在大数据量情况下有着优良的查询性能。 经常用于根据key检索value的业务场景。

    15.3.2 常用的方法

    image.png

    15.3.3 元素放入HashMap集合的原理

  • 使用元素的key调用hashCode方法获取对应的哈希码值,再由某种哈希算法计算在数组中的索引 位置。

  • 若该位置没有元素,则将该键值对直接放入即可。
  • 若该位置有元素,则使用key与已有元素依次比较哈希值,若哈希值不相同,则将该元素直接放 入。
  • 若key与已有元素的哈希值相同,则使用key调用equals方法与已有元素依次比较。
  • 若相等则将对应的value修改,否则将键值对直接放入即可。

    15.3.4 相关的常量

  • DEFAULT_INITIAL_CAPACITY : HashMap的默认容量是16。

  • DEFAULT_LOAD_FACTOR:HashMap的默认加载因子是0.75。
  • threshold:扩容的临界值,该数值为:容量*填充因子,也就是12。
  • TREEIFY_THRESHOLD:若Bucket中链表长度大于该默认值则转化为红黑树存储,该数值是8。
  • MIN_TREEIFY_CAPACITY:桶中的Node被树化时最小的hash表容量,该数值是64。

    15.4 Collections类

    15.4.1 基本概念

  • java.util.Collections类主要提供了对集合操作或者返回集合的静态方法。

    15.4.2 常用的方法

    image.png

第十六章 异常机制和File类

16.1 异常机制(重点)

16.1.1 基本概念

  • 异常就是”不正常”的含义,在Java语言中主要指程序执行中发生的不正常情况。
  • java.lang.Throwable类是Java语言中错误(Error)和异常(Exception)的超类。
  • 其中Error类主要用于描述Java虚拟机无法解决的严重错误,通常无法编码解决,如:JVM挂掉了 等。
  • 其中Exception类主要用于描述因编程错误或偶然外在因素导致的轻微错误,通常可以编码解决, 如:0作为除数等。

    16.1.2 异常的分类

  • java.lang.Exception类是所有异常的超类,主要分为以下两种:

RuntimeException - 运行时异常,也叫作非检测性异常
IOException和其它异常 - 其它异常,也叫作检测性异常,所谓检测性异常就是指在编译阶段都能 被 编译器检测出来的异常。

  • 其中RuntimeException类的主要子类:

ArithmeticException类 - 算术异常
ArrayIndexOutOfBoundsException类 - 数组下标
越界异常NullPointerException - 空指针异常
ClassCastException - 类型转换异常
NumberFormatException - 数字格式异常

  • 注意: 当程序执行过程中发生异常但又没有手动处理时,则由Java虚拟机采用默认方式处理异常,而默认 处理方式就是:打印异常的名称、异常发生的原因、异常发生的位置以及终止程序。

    16.1.3 异常的避免

  • 在以后的开发中尽量使用if条件判断来避免异常的发生。

  • 但是过多的if条件判断会导致程序的代码加长、臃肿,可读性差。

    16.1.4 异常的捕获

  • 语法格式

try {编写可能发生异常的代码;
}
catch(异常类型 引用变量名) {
编写针对该类异常的处理代码;
}
… finally {
编写无论是否发生异常都要执行的代码;
}

  • 注意事项

a.当需要编写多个catch分支时,切记小类型应该放在大类型的前面;
b.懒人的写法:
catch(Exception e) {}
c.finally通常用于进行善后处理,如:关闭已经打开的文件等。

  • 执行流程
    try {

a;
b; - 可能发生异常的语句
c;
}catch(Exception ex) { d;
}finally { e;
}
当没有发生异常时的执行流程:a b c e;
当发生异常时的执行流程:a b d e;

16.1.5 异常的抛出

  • 基本概念

在某些特殊情况下有些异常不能处理或者不便于处理时,就可以将该异常转移给该方法的调用者, 这种方法就叫异常的抛出。当方法执行时出现异常,则底层生成一个异常类对象抛出,此时异常代 码后续的代码就不再执行。

  • 语法格式
    访问权限 返回值类型 方法名称(形参列表) throws 异常类型1,异常类型2,…{ 方法体; }如:

public void show() throws IOException{}

  • 方法重写的原则

a.要求方法名相同、参数列表相同以及返回值类型相同,从jdk1.5开始支持返回子类类型;b.要求方法的访问权限不能变小,可以相同或者变大;
c.要求方法不能抛出更大的异常;

  • 注意: 子类重写的方法不能抛出更大的异常、不能抛出平级不一样的异常,但可以抛出一样的异常、更小 的异常以及不抛出异常。
  • 经验分享

若父类中被重写的方法没有抛出异常时,则子类中重写的方法只能进行异常的捕获处理。
若一个方法内部又以递进方式分别调用了好几个其它方法,则建议这些方法内可以使用抛出 的方法处理到最后一层进行捕获方式处理。

16.1.6 自定义异常

  • 基本概念

当需要在程序中表达年龄不合理的情况时,而Java官方又没有提供这种针对性的异常,此时就需要 程序员自定义异常加以描述。

  • 实现流程

a.自定义xxxException异常类继承Exception类或者其子类。
b.提供两个版本的构造方法,一个是无参构造方法,另外一个是字符串作为参数的构造方法。
异常的产生throw new 异常类型(实参
如: throw new AgeException(“年龄不合理!!!”);

  • Java采用的异常处理机制是将异常处理的程序代码集中在一起,与正常的程序代码分开,使得程序 简洁、优雅,并易于维护。

    16.2 File类(重点)

    16.2.1 基本概念

  • java.io.File类主要用于描述文件或目录路径的抽象表示信息,可以获取文件或目录的特征信息, 如:大小等。

    16.2.2 常用的方法

    image.png

第十七章 IO流

17.1 IO流的概念

IO就是Input和Output的简写,也就是输入和输出的含义。IO流就是指读写数据时像流水一样从一端流到另外一端,因此得名为“流”。

17.2 基本分类

  • 按照读写数据的基本单位不同,分为 字节流 和 字符流。 其中字节流主要指以字节为单位进行数据读写的流,可以读写任意类型的文件。 其中字符流主要指以字符(2个字节)为单位进行数据读写的流,只能读写文本文件。
  • 按照读写数据的方向不同,分为 输入流 和 输出流(站在程序的角度)。 其中输入流主要指从文件中读取数据内容输入到程序中,也就是读文件。 其中输出流主要指将程序中的数据内容输出到文件中,也就是写文件。
  • 按照流的角色不同分为节点流和处理流。 其中节点流主要指直接和输入输出源对接的流。 其中处理流主要指需要建立在节点流的基础之上的流。

    17.3 体系结构

    image.png

    17.4 相关流的详解
    17.4.1 FileWriter类(重点)

    (1)基本概念

  • java.io.FileWriter类主要用于将文本内容写入到文本文件。

(2)常用的方法
image.png

17.4.3 FileOutputStream类(重点)

(1)基本概念

  • java.io.FileOutputStream类主要用于将图像数据之类的原始字节流写入到输出流中。

    (2)常用的方法

    image.png

    17.4.4 FileInputStream类(重点)

    (1)基本概念

  • java.io.FileInputStream类主要用于从输入流中以字节流的方式读取图像数据等。

    (2)常用的方法

    image.png

    17.4.5 BufferedOutputStream类(重点)

    (1)基本概念

    java.io.BufferedOutputStream类主要用于描述缓冲输出流,此时不用为写入的每个字节调用底层 系统。

    (2)常用的方法

    image.png

17.4.6 BufferedInputStream类(重点)

(1)基本概念

  • java.io.BufferedInputStream类主要用于描述缓冲输入

    (2)常用的方法

    image.png

    17.4.7 BufferedWriter类(重点)

    (1)基本概念

    java.io.BufferedWriter类主要用于写入单个字符、字符数组以及字符串到输出流中。

    (2)常用的方法

image.png

17.4.8 BufferedReader类(重点)

(1)基本概念

  • java.io.BufferedReader类用于从输入流中读取单个字符、字符数组以及字符串。

    (2)常用的方法

    image.png

    17.4.9 PrintStream类

    (1)基本概念

  • java.io.PrintStream类主要用于更加方便地打印各种数据内容。

    (2)常用的方法

    image.png

17.4.10 PrintWriter类

(1)基本概念

  • java.io.PrintWriter类主要用于将对象的格式化形式打印到文本输出流。

    (2)常用的方法

    image.png

17.4.11 OutputStreamWriter类

(1)基本概念

  • java.io.OutputStreamWriter类主要用于实现从字符流到字节流的转换。

    (2)常用的方法

    image.png

17.4.12 InputStreamReader类

(1)基本概念

  • java.io.InputStreamReader类主要用于实现从字节流到字符流的转换

    (2)常用的方法

    image.png

17.4.13 字符编码

(1)编码表的由来

  • 计算机只能识别二进制数据,早期就是电信号。为了方便计算机可以识别各个国家的文字,就需要 将各个国家的文字采用数字编号的方式进行描述并建立对应的关系表,该表就叫做编码表。

    (2)常见的编码表

  • ASCII:美国标准信息交换码, 使用一个字节的低7位二位进制进行表示。

  • ISO8859-1:拉丁码表,欧洲码表,使用一个字节的8位二进制进行表示。
  • GB2312:中国的中文编码表,最多使用两个字节16位二进制为进行表示。
  • GBK:中国的中文编码表升级,融合了更多的中文文字符号,最多使用两个字节16位二进制位表 示。
  • Unicode:国际标准码,融合了目前人类使用的所有字符,为每个字符分配唯一的字符码。所有的 文字都用两个字节16位二进制位来表示。

    (3)编码的发展

  • 面向传输的众多 UTF(UCS Transfer Format)标准出现了,UTF-8就是每次8个位传输数据,而UTF-16就是每次16个位。这是为传输而设计的编码并使编码无国界,这样就可以显示全世界上所 有文化的字符了

  • Unicode只是定义了一个庞大的、全球通用的字符集,并为每个字符规定了唯一确定的编号,具体 存储成什么样的字节流,取决于字符编码方案。推荐的Unicode编码是UTF-8和UTF-16。
  • UTF-8:变长的编码方式,可用1-4个字节来表示一个字符。

    17.4.14 DataOutputStream类(了解)

    (1)基本概念

  • java.io.DataOutputStream类主要用于以适当的方式将基本数据类型写入输出流中

    (2)常用的方法

    image.png

17.4.15 DataInputStream类(了解)

(1)基本概念

  • java.io.DataInputStream类主要用于从输入流中读取基本数据类型的数据。

    (2)常用的方法

    image.png

17.4.16 ObjectOutputStream类(重点)

(1)基本概念

  • java.io.ObjectOutputStream类主要用于将一个对象的所有内容整体写入到输出流中。
  • 只能将支持 java.io.Serializable 接口的对象写入流中。
  • 类通过实现 java.io.Serializable 接口以启用其序列化功能。
  • 所谓序列化主要指将一个对象需要存储的相关信息有效组织成字节序列的转化过程。

    (2)常用的方法

    image.png

    (3)序列化版本号

  • 序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如 果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常(InvalidCastException)。

    (4)transient关键字

  • transient是Java语言的关键字,用来表示一个域不是该对象串行化的一部分。当一个对象被串行 化的时候,transient型变量的值不包括在串行化的表示中,然而非transient型的变量是被包括进 去的。

    (5)经验的分享

  • 当希望将多个对象写入文件时,通常建议将多个对象放入一个集合中,然后将集合这个整体看做一 个对象写入输出流中,此时只需要调用一次readObject方法就可以将整个集合的数据读取出来, 从而避免了通过返回值进行是否达到文件末尾的判断。

    17.4.18 RandomAccessFile类

    (1)基本概念

  • java.io.RandomAccessFile类主要支持对随机访问文件的读写操作。

    (2)常用的方法

    image.png

第十八章 多线程

18.1 基本概念

18.1.1 程序和进程的概念

  • 程序 - 数据结构 + 算法,主要指存放在硬盘上的可执行文件。
  • 进程 - 主要指运行在内存中的可执行文件。
  • 目前主流的操作系统都支持多进程,为了让操作系统同时可以执行多个任务,但进程是重量级的, 也就是新建一个进程会消耗CPU和内存空间等系统资源,因此进程的数量比较局限。

    18.1.2 线程的概念

  • 为了解决上述问题就提出线程的概念,线程就是进程内部的程序流,也就是说操作系统内部支持多 进程的,而每个进程的内部又是支持多线程的,线程是轻量的,新建线程会共享所在进程的系统资 源,因此目前主流的开发都是采用多线程。

  • 多线程是采用时间片轮转法来保证多个线程的并发执行,所谓并发就是指宏观并行微观串行的机 制。

    18.2 线程的创建(重中之重)

    18.2.1 Thread类的概念

  • java.lang.Thread类代表线程,任何线程对象都是Thread类(子类)的实例。

  • Thread类是线程的模板,封装了复杂的线程开启等操作,封装了操作系统的差异性。

    18.2.2 创建方式

  • 自定义类继承Thread类并重写run方法,然后创建该类的对象调用start方法。

  • 自定义类实现Runnable接口并重写run方法,创建该类的对象作为实参来构造Thread类型的对 象,然后使用Thread类型的对象调用start方法。

    18.2.3 相关的方法

    image.png

18.2.4 执行流程

  • 执行main方法的线程叫做主线程,执行run方法的线程叫做新线程/子线程。
  • main方法是程序的入口,对于start方法之前的代码来说,由主线程执行一次,当start方法调用成 功后线程的个数由1个变成了2个,新启动的线程去执行run方法的代码,主线程继续向下执行,两 个线程各自独立运行互不影响。
  • 当run方法执行完毕后子线程结束,当main方法执行完毕后主线程结束。
  • 两个线程执行没有明确的先后执行次序,由操作系统调度算法来决定。

    18.2.5 方式的比较

  • 继承Thread类的方式代码简单,但是若该类继承Thread类后则无法继承其它类,而实现Runnable接口的方式代码复杂,但不影响该类继承其它类以及实现其它接口,因此以后的开发中 推荐使用第二种方式。

    18.2.6 匿名内部类的方式

  • 使用匿名内部类的方式来创建和启动线程。

    18.3 线程的生命周期(熟悉)

    image.png

  • 新建状态 - 使用new关键字创建之后进入的状态,此时线程并没有开始执行。

  • 就绪状态 - 调用start方法后进入的状态,此时线程还是没有开始执行。
  • 运行状态 - 使用线程调度器调用该线程后进入的状态,此时线程开始执行,当线程的时间片执行完 毕后任务没有完成时回到就绪状态。
  • 消亡状态 - 当线程的任务执行完成后进入的状态,此时线程已经终止。
  • 阻塞状态 - 当线程执行的过程中发生了阻塞事件进入的状态,如:sleep方法。 阻塞状态解除后进入就绪状态。

    18.4 线程的编号和名称(熟悉)

    image.png

    18.5 常用的方法(重点)

    image.png

18.6 线程同步机制(重点)

18.6.1 基本概念

  • 当多个线程同时访问同一种共享资源时,可能会造成数据的覆盖等不一致性问题,此时就需要对线 程之间进行通信和协调,该机制就叫做线程的同步机制。
  • 多个线程并发读写同一个临界资源时会发生线程并发安全问题。
  • 异步操作:多线程并发的操作,各自独立运行。
  • 同步操作:多线程串行的操作,先后执行的顺序。

    18.6.2 解决方案

  • 由程序结果可知:当两个线程同时对同一个账户进行取款时,导致最终的账户余额不合理。

  • 引发原因:线程一执行取款时还没来得及将取款后的余额写入后台,线程二就已经开始取款。
  • 解决方案:让线程一执行完毕取款操作后,再让线程二执行即可,将线程的并发操作改为串行操 作。
  • 经验分享:在以后的开发尽量减少串行操作的范围,从而提高效率。

    18.6.3 实现方式

  • 在Java语言中使用synchronized关键字来实现同步/对象锁机制从而保证线程执行的原子性,具体 方式如下:

使用同步代码块的方式实现部分代码的锁定,格式如下:
synchronized(类类型的引用) {
编写所有需要锁定的代码;
}

  • 使用同步方法的方式实现所有代码的锁定。

直接使用synchronized关键字来修饰整个方法即可 该方式等价于:
synchronized(this) { 整个方法体的代码 }

18.6.4 静态方法的锁定

  • 当我们对一个静态方法加锁,如:
    public synchronized static void xxx(){….}
  • 那么该方法锁的对象是类对象。每个类都有唯一的一个类对象。获取类对象的方式:类名.class。
  • 静态方法与非静态方法同时使用了synchronized后它们之间是非互斥关系的。
  • 原因在于:静态方法锁的是类对象而非静态方法锁的是当前方法所属对象。

    18.6.5 注意事项

  • 使用synchronized保证线程同步应当注意:

1.多个需要同步的线程在访问同步块时,看到的应该是同一个锁对象引用。
2.在使用同步块时应当尽量减少同步范围以提高并发的执行效率。

18.6.6 线程安全类和不安全类

  • StringBuffer类是线程安全的类,但StringBuilder类不是线程安全的类。
  • Vector类和 Hashtable类是线程安全的类,但ArrayList类和HashMap类不是线程安全的类。
  • Collections.synchronizedList() 和 Collections.synchronizedMap()等方法实现安全。

    18.6.7 死锁的概念

  • 线程一执行的代码:

public void run(){
synchronized(a){ //持有对象锁a,等待对象锁b
synchronized(b){编写锁定的代码;
} }
}

  • 线程二执行的代码:

public void run(){
synchronized(b){ //持有对象锁b,等待对象锁a
synchronized(a){编写锁定的代码;
} }
}

  • 注意:

在以后的开发中尽量减少同步的资源,减少同步代码块的嵌套结构的使用!

18.6.8 使用Lock(锁)实现线程同步

(1)基本概念

  • 从Java5开始提供了更强大的线程同步机制—使用显式定义的同步锁对象来实现。
  • java.util.concurrent.locks.Lock接口是控制多个线程对共享资源进行访问的工具。
  • 该接口的主要实现类是ReentrantLock类,该类拥有与synchronized相同的并发性,在以后的线程 安全控制中,经常使用ReentrantLock类显式加锁和释放锁。

    (2)常用的方法

    image.png

(3)与synchronized方式的比较

  • Lock是显式锁,需要手动实现开启和关闭操作,而synchronized是隐式锁,执行锁定代码后自动 释放。
  • Lock只有同步代码块方式的锁,而synchronized有同步代码块方式和同步方法两种锁。
  • 使用Lock锁方式时,Java虚拟机将花费较少的时间来调度线程,因此性能更好。

    18.6.9 Object类常用的方法

    image.png

18.6.10 线程池(熟悉)

(1)实现Callable接口

  • 从Java5开始新增加创建线程的第三种方式为实现java.util.concurrent.Callable接口。
  • 常用的方法如下:

image.png

(2)FutureTask类

  • java.util.concurrent.FutureTask类用于描述可取消的异步计算,该类提供了Future接口的基本实 现,包括启动和取消计算、查询计算是否完成以及检索计算结果的方法,也可以用于获取方法调用 后的返回结果。
  • 常用的方法如下:

    image.png

(3)线程池的由来

  • 在服务器编程模型的原理,每一个客户端连接用一个单独的线程为之服务,当与客户端的会话结束 时,线程也就结束了,即每来一个客户端连接,服务器端就要创建一个新线程。
  • 如果访问服务器的客户端很多,那么服务器要不断地创建和销毁线程,这将严重影响服务器的性 能。

    (4)概念和原理

  • 线程池的概念:首先创建一些线程,它们的集合称为线程池,当服务器接受到一个客户请求后,就 从线程池中取出一个空闲的线程为之服务,服务完后不关闭该线程,而是将该线程还回到线程池 中。

  • 在线程池的编程模式下,任务是提交给整个线程池,而不是直接交给某个线程,线程池在拿到任务 后,它就在内部找有无空闲的线程,再把任务交给内部某个空闲的线程,任务是提交给整个线程 池,一个线程同时只能执行一个任务,但可以同时向一个线程池提交多个任务。

    (5)相关类和方法

  • 从Java5开始提供了线程池的相关类和接口:java.util.concurrent.Executors类和java.util.concurrent.ExecutorService接口。

  • 其中Executors是个工具类和线程池的工厂类,可以创建并返回不同类型的线程池,常用方法如

下:
image.png

其中ExecutorService接口是真正的线程池接口,主要实现类是ThreadPoolExecutor,常用方法
如下:
image.png

第十九章 网络编程

19.1 网络编程的常识

  • 目前主流的网络通讯软件有:微信、QQ、飞信、阿里旺旺、陌陌、探探、…

    19.1.1 七层网络模型

  • OSI(Open System Interconnect),即开放式系统互联,是ISO(国际标准化组织)组织在1985年研究的网络互连模型。

  • OSI七层模型和TCP/IP五层模型的划分如下:

image.png

  • 当发送数据时,需要对发送的内容按照上述七层模型进行层层加包后发送出去。
  • 当接收数据时,需要对接收的内容按照上述七层模型相反的次序层层拆包并显示出来。

    19.1.2 相关的协议(笔试题)

    (1)协议的概念

  • 计算机在网络中实现通信就必须有一些约定或者规则,这种约定和规则就叫做通信协议,通信协议 可以对速率、传输代码、代码结构、传输控制步骤、出错控制等制定统一的标准。

    (2)TCP协议

  • 传输控制协议(Transmission Control Protocol),是一种面向连接的协议,类似于打电话。

  1. 建立连接 => 进行通信 => 断开连接
  2. 在传输前采用”三次握手”方式。
  3. 在通信的整个过程中全程保持连接,形成数据传输通道。
  4. 保证了数据传输的可靠性和有序性。
  5. 是一种全双工的字节流通信方式,可以进行大数据量的传输。
  6. 传输完毕后需要释放已建立的连接,发送数据的效率比较低。

    (3)UDP协议

  • 用户数据报协议(User Datagram Protocol),是一种非面向连接的协议,类似于写信。
  1. 在通信的整个过程中不需要保持连接,其实是不需要建立连接。
  2. 不保证数据传输的可靠性和有序性。
  3. 是一种全双工的数据报通信方式,每个数据报的大小限制在64K内。
  4. 发送数据完毕后无需释放资源,开销小,发送数据的效率比较高,速度快。

19.1.3 IP地址(重点)

  • 192.168.1.1 - 是绝大多数路由器的登录地址,主要配置用户名和密码以及Mac过滤。
  • IP地址是互联网中的唯一地址标识,本质上是由32位二进制组成的整数,叫做IPv4,当然也有128位二进制组成的整数,叫做IPv6,目前主流的还是IPv4。
  • 日常生活中采用点分十进制表示法来进行IP地址的描述,将每个字节的二进制转化为一个十进制整数,不同的整数之间采用小数点隔开。 如:0x01020304 => 1.2.3.4
  • 查看IP地址的方式:

Windows系统:在dos窗口中使用ipconfig或ipconfig/all命令即可
Unix/linux系统:在终端窗口中使用ifconfig或/sbin/ifconfig命令即可

  • 特殊的地址
    本地回环地址(hostAddress):127.0.0.1 主机名(hostName):localhost

    19.1.4 端口号(重点)

  • IP地址 - 可以定位到具体某一台设备。

  • 端口号 - 可以定位到该设备中具体某一个进程。
  • 端口号本质上是16位二进制组成的整数,表示范围是:0 ~ 65535,其中0 ~ 1024之间的端口号通 常被系统占用,建议编程从1025开始使用。
  • 特殊的端口:

HTTP:80 FTP:21 Oracle:1521 MySQL:3306 Tomcat:8080

  • 网络编程需要提供:IP地址 + 端口号,组合在一起叫做网络套接字:Socket。

    19.2 基于tcp协议的编程模型(重点)

    19.2.1 C/S架构的简介

  • 在C/S模式下客户向服务器发出服务请求,服务器接收请求后提供服务。

  • 例如:在一个酒店中,顾客找服务员点菜,服务员把点菜单通知厨师,厨师按点菜单做好菜后让服 务员端给客户,这就是一种C/S工作方式。如果把酒店看作一个系统,服务员就是客户端,厨师就 是服务器。这种系统分工和协同工作的方式就是C/S的工作方式。
  • 客户端部分:为每个用户所专有的,负责执行前台功能。
  • 服务器部分:由多个用户共享的信息与功能,招待后台服务。

    19.2.2 编程模型

  • 服务器:
    (1)创建ServerSocket类型的对象并提供端口号;

(2)等待客户端的连接请求,调用accept()方法;
(3)使用输入输出流进行通信;
(4)关闭Socket;

  • 客户端:

(1)创建Socket类型的对象并提供服务器的IP地址和端口号;
(2)使用输入输出流进行通信;
(3)关闭Socket;

19.2.3 相关类和方法的解析

(1)ServerSocket类

  • java.net.ServerSocket类主要用于描述服务器套接字信息(大插排)。
  • 常用的方法如下:

image.png

(2)Socket类

  • java.net.Socket类主要用于描述客户端套接字,是两台机器间通信的端点(小插排)。
  • 常用的方法如下:

image.png

(3)注意事项

  • 客户端 Socket 与服务器端 Socket 对应, 都包含输入和输出流。
  • 客户端的socket.getInputStream() 连接于服务器socket.getOutputStream()。
  • 客户端的socket.getOutputStream()连接于服务器socket.getInputStream()

    19.3 基于udp协议的编程模型(熟悉)

    19.3.1 编程模型

  • 接收方:
    (1)创建DatagramSocket类型的对象并提供端口号;

(2)创建DatagramPacket类型的对象并提供缓冲区;
(3)通过Socket接收数据内容存放到Packet中,调用receive方法;
(4)关闭Socket;

  • 发送方:
    (1)创建DatagramSocket类型的对象;

(2)创建DatagramPacket类型的对象并提供接收方的通信地址;
(3)通过Socket将Packet中的数据内容发送出去,调用send方法;
(4)关闭Socket;

19.3.2 相关类和方法的解析(1)

DatagramSocket类

  • java.net.DatagramSocket类主要用于描述发送和接收数据报的套接字(邮局)。 换句话说,该类就是包裹投递服务的发送或接收点。
  • 常用的方法如下:

    image.png

    (2)DatagramPacket类

  • java.net.DatagramPacket类主要用于描述数据报,数据报用来实现无连接包裹投递服务。

  • 常用的方法如下:

    image.png

(3)InetAddress类

  • java.net.InetAddress类主要用于描述互联网通信地址信息。
  • 常用的方法如下:

    image.png

19.4 URL类(熟悉)

19.4.1 基本概念

  • java.net.URL(Uniform Resource Identifier)类主要用于表示统一的资源定位器,也就是指向万 维网上“资源”的指针。这个资源可以是简单的文件或目录,也可以是对复杂对象的引用,例如对数 据库或搜索引擎的查询等。
  • 通过URL可以访问万维网上的网络资源,最常见的就是www和ftp站点,浏览器通过解析给定的URL可以在网络上查找相应的资源。
  • URL的基本结构如下:<传输协议>://<主机名>:<端口号>/<资源地址>

19.4.2 常用的方法

image.png

19.4.3 URLConnection类

(1)基本概念

  • java.net.URLConnection类是个抽象类,该类表示应用程序和URL之间的通信链接的所有类的超

类,主要实现类有支持HTTP特有功能的HttpURLConnection类。

(2)HttpURLConnection类的常用方法

image.png

第二十章 反射机制

20.1 基本概念

  • 通常情况下编写代码都是固定的,无论运行多少次执行的结果也是固定的,在某些特殊场合中编写 代码时不确定要创建什么类型的对象,也不确定要调用什么样的方法,这些都希望通过运行时传递 的参数来决定,该机制叫做动态编程技术,也就是反射机制。
  • 通俗来说,反射机制就是用于动态创建对象并且动态调用方法的机制。
  • 目前主流的框架底层都是采用反射机制实现的。
  • 如:
    Person p = new Person(); - 表示声明Person类型的引用指向Person类型的对象

p.show(); - 表示调用Person类中的成员方法show

20.2 Class类

20.2.1 基本概念

  • java.lang.Class类的实例可以用于描述Java应用程序中的类和接口,也就是一种数据类型。
  • 该类没有公共构造方法,该类的实例由Java虚拟机和类加载器自动构造完成,本质上就是加载到内 存中的运行时类。

    20.2.2 获取Class对象的方式

  • 使用数据类型.class的方式可以获取对应类型的Class对象(掌握)。

  • 使用引用/对象.getClass()的方式可以获取对应类型的Class对象。
  • 使用包装类.TYPE的方式可以获取对应基本数据类型的Class对象。
  • 使用Class.forName()的方式来获取参数指定类型的Class对象(掌握)。
  • 使用类加载器ClassLoader的方式获取指定类型的Class对象。

20.2.3 常用的方法(掌握)

截屏2021-06-30 下午10.10.23.png

20.3 Constructor类

20.3.1 基本概念

  • java.lang.reflect.Constructor类主要用于描述获取到的构造方法信息

    20.3.2 Class类的常用方法

    image.png

20.3.3 Constructor类的常用方法

image.png

20.4 Field类

20.4.1 基本概念

  • java.lang.reflect.Field类主要用于描述获取到的单个成员变量信息。

    20.4.2 Class类的常用方法

    image.png

    20.4.3 Field类的常用方法

    image.png

    20.5 Method类

    20.5.1 基本概念

  • java.lang.reflect.Method类主要用于描述获取到的单个成员方法信息。

    20.5.2 Class类的常用方法

    image.png

    20.6 获取其它结构信息

    image.png

第二十一章 常用设计原则和设计模式

21.1 常用的设计原则(记住)

21.1.1 软件开发的流程

  • 需求分析文档、概要设计文档、详细设计文档、编码和测试、安装和调试、维护和升级

    21.1.2 常用的设计原则

  • 开闭原则(Open Close Principle)

对扩展开放对修改关闭,为了使程序的扩展性好,易于维护和升级。

  • 里氏代换原则(Liskov Substitution Principle)

任何基类可以出现的地方,子类一定可以出现,多使用多态的方式。

  • 依赖倒转原则(Dependence Inversion Principle)

尽量多依赖于抽象类或接口而不是具体实现类,对子类具有强制性和规范性

  • 接口隔离原则(Interface Segregation Principle)

尽量多使用小接口而不是大接口,避免接口的污染,降低类之间耦合度。

  • 迪米特法则(最少知道原则)(Demeter Principle)

一个实体应当尽量少与其他实体之间发生相互作用,使系统功能模块相对独立。高内聚,低耦合。

  • 合成复用原则(Composite Reuse Principle)

尽量多使用合成/聚合的方式,而不是继承的方式。

21.2 常用的设计模式

21.2.1 基本概念

  • 设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验 的总结。
  • 设计模式就是一种用于固定场合的固定套路。

    21.2.2 基本分类

  • 创建型模式 - 单例设计模式、工厂方法模式、抽象工厂模式、…

  • 结构型模式 - 装饰器模式、代理模式、…
  • 行为型模式 - 模板设计模式、…

    21.3 设计模式详解(重点)

    21.3.1 单例设计模式

  • 单例设计模式主要分为:饿汉式 和 懒汉式,懒汉式需要对多线程进行同步处理。

    21.3.2 普通工厂模式

    (1)基本概念

    普通工厂方法模式就是建立一个工厂类,对实现了同一接口的不同实现类进行实例的创建。

    (2)类图结构

    image.png

(3)主要缺点

在普通工厂方法模式中,如果传递的字符串出错,则不能正确创建对象,并且可能出现空指针异常

21.3.3 多个工厂方法模式

(1)类图结构

image.png

(2)主要缺点

在多个工厂方法模式中,为了能够正确创建对象,先需要创建工厂类的对象才能调用工厂类中的生
产方法。

21.3.4 静态工厂方法模式

(1)类图结构

image.png

(2)实际意义

工厂方法模式适合:凡是出现了大量的产品需要创建且具有共同的接口时,可以通过工厂方法模式进行创建。

(3)主要缺点

工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序生产新的产 品,就必须对工厂类的代码进行修改,这就违背了开闭原则。

21.3.5 抽象工厂模式

(1)类图结构

image.png

21.3.6 装饰器模式

(1)基本概念

装饰器模式就是给一个对象动态的增加一些新功能,要求装饰对象和被装饰对象实现同一个接口, 装饰对象持有被装饰对象的实例。

(2)类图结构

  1. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/12720928/1625215300245-2812ce47-12b9-46a1-885c-4d9bc7434aa2.png#align=left&display=inline&height=191&margin=%5Bobject%20Object%5D&name=image.png&originHeight=880&originWidth=1606&size=168111&status=done&style=none&width=348)

(3)实际意义

  • 可以实现一个类功能的扩展。
  • 可以动态的增加功能,而且还能动态撤销(继承不行)。
  • 缺点:产生过多相似的对象,不易排错。

    21.3.7 代理模式

    (1)基本概念

  • 代理模式就是找一个代理类替原对象进行一些操作。

  • 比如我们在租房子的时候找中介,再如我们打官司需要请律师,中介和律师在这里就是我们的代 理。

    (2)类图结构

    image.png

(3)实际意义

  • 如果在使用的时候需要对原有的方法进行改进,可以采用一个代理类调用原有方法,并且对产生的 结果进行控制,这种方式就是代理模式。
  • 使用代理模式,可以将功能划分的更加清晰,有助于后期维护。

    (4)代理模式和装饰器模式的比较

  • 装饰器模式通常的做法是将原始对象作为一个参数传给装饰者的构造器,而代理模式通常在一个代理类中创建一个被代理类的对象。

  • 装饰器模式关注于在一个对象上动态的添加方法,然而代理模式关注于控制对对象的访问。

    21.3.8 模板方法模式

    (1)基本概念

    模板方法模式主要指一个抽象类中封装了一个固定流程,流程中的具体步骤可以由不同子类进行不同的实现,通过抽象类让固定的流程产生不同的结果。

    (2)类图结构

    image.png

    (3)实际意义

  • 将多个子类共有且逻辑基本相同的内容提取出来实现代码复用。

  • 不同的子类实现不同的效果形成多态,有助于后期维护。


第二十二章 新特性

22.1 Java8的新特性

22.1.1 Java8的概述

  • Java8是 Java 语言的一个重要版本,该版本于2014年3月发布,是自Java5以来最具革命性的版本,这个版本包含语言、编译器、库、工具和JVM等方面的十多个新特性。

    22.1.2 函数式接口

  • 函数式接口主要指只包含一个抽象方法的接口,如:java.lang.Runnable、java.util.Comparator接口等。

  • Java8提供@FunctionalInterface注解来定义函数式接口,若定义的接口不符合函数式的规范便会 报错。
  • Java8中增加了java.util.function包,该包包含了常用的函数式接口,具体如下:

image.png

22.1.3 Lambda表达式

  • Lambda 表达式是实例化函数式接口的重要方式,使用 Lambda 表达式可以使代码变的更加简洁 紧凑。
  • lambda表达式:参数列表、箭头符号->和方法体组成,而方法体中可以是表达式,也可以是语句 块。
  • 语法格式:(参数列表) -> { 方法体; } - 其中()、参数类型、{} 以及return关键字 可以省略。

    22.1.4 方法引用

  • 方法引用主要指通过方法的名字来指向一个方法而不需要为方法引用提供方法体,该方法的调用交 给函数式接口执行。

  • 方法引用使用一对冒号 :: 将类或对象与方法名进行连接,通常使用方式如下:

image.png

  • 方法引用是在特定场景下lambda表达式的一种简化表示,可以进一步简化代码的编写使代码更加紧凑简洁,从而减少冗余代码。

    22.1.5 Stream接口

    (1)基本概念

  • java.util.stream.Stream接口是对集合功能的增强,可以对集合元素进行复杂的查找、过滤、筛选 等操作。

  • Stream接口借助于Lambda 表达式极大的提高编程效率和程序可读性,同时它提供串行和并行两 种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势。

    (2)使用步骤

  • 创建Stream,通过一个数据源来获取一个流。

  • 转换Stream,每次转换返回一个新的Stream对象。
  • 对Stream进行聚合操作并产生结果。

    (3)创建方式

  • 方式一:通过调用集合的默认方法来获取流,如:default Stream stream()

  • 方式二:通过数组工具类中的静态方法来获取流,如:static IntStream stream(int[] array)
  • 方式三:通过Stream接口的静态方法来获取流,如:static Stream of(T… values)
  • 方式四:通过Stream接口的静态方法来获取流,static Stream generate(Supplier<? extends T> s)

    (4)中间操作

  • 筛选与切片的常用方法如下:

image.png

  • 映射的常用方法如下:

image.png

  • 排序的常用方法如下:

image.png

(5)终止操作

  • 匹配与查找的常用方法如下:

image.png

  • 规约的常用方法如下:

image.png

  • 收集的常用方法如下:

image.png

22.1.6 Optional类

(1)基本概念

  • java.util.Optional类可以理解为一个简单的容器,其值可能是null或者不是null,代表一个值存在 或不存在。
  • 该类的引入很好的解决空指针异常,不用显式进行空值检测。

    (2)常用的方法

    image.png

    22.2 Java9的新特性

    22.2.1 Java9的概述

  • Java9发布于2017年9月发布,带来了很多新特性,其中最主要的变化是模块化系统。

  • 模块就是代码和数据的封装体,模块的代码被组织成多个包,每个包中包含Java类和接口,模块的 数据则包括资源文件和其他静态信息。

    22.2.2 模块化的使用

    (1)语法格式

  • 在 module-info.java 文件中,我们可以用新的关键词module来声明一个模块,具体如下:

module 模块名称 {
}

(2)模块化的优势

  • 减少内存的开销。
  • 可简化各种类库和大型应用的 开发和维护。
  • 安全性,可维护性,提高性能。

    22.2.3 钻石操作符的使用升级

  • 在Java9中允许在匿名内部类的使用中使用钻石操作符。

    22.2.4 集合工厂方法

    (1)基本概念

  • Java9的List、Set和Map集合中增加了静态工厂方法of实现不可变实例的创建。

  • 不可变体现在无法添加、修改和删除它们的元素。
  • 不允许添加null元素对象。

    (2)实际意义

  • 保证线程安全:在并发程序中既保证线程安全性,也大大增强了并发时的效率。

  • 被不可信的类库使用时会很安全。
  • 如果一个对象不需要支持修改操作,将会节省空间和时间的开销。
  • 可以当作一个常量来对待,并且这个对象在以后也不会被改变。

    22.2.5 InputStream的增强

  • InputStream类中提供了transferTo方法实现将数据直接传输到OutputStream中。

    22.3 Java10的新特性

    22.3.1 Java10的概述

  • Java10于2018年3月发布,改进的关键点包括一个本地类型推断、一个垃圾回收的增强。

  • Java10计划只是一个短期版本,因此公开更新将在六个月内结束,9月份发布的Java11将是Java的 长期支持(LTS)版本,LTS版本的发布每三年发布一次。

    22.3.2 局部变量类型推断

    (1)基本概念

  • Java10可以使用var作为局部变量类型推断标识符,此符号仅适用于局部变量,增强for循环的索 引,以及传统for循环的本地变量。

  • 它不能使用于方法形式参数,构造函数形式参数,方法返回类型,字段,catch形式参数或任何其 他类型的变量声明。

    (2)实际意义

  • 标识符var不是关键字,只是一个保留的类型名称。这意味着var用作变量,方法名或包名的代码不 会受到影响,但var不能作为类或则接口的名字。

  • 避免了信息冗余。
  • 对齐了变量名。
  • 更容易阅读。

    22.4 Java11的新特性

    22.4.1 Java11的概述

  • Java11于2018年9月正式发布这是 Java大版本周期变化 后的第一个长期支持版本,非常值得关注。

    22.4.2 简化的编译运行操作

  • 在Java11中可以使用java命令一次性进行编译和运行操作。 执行源文件中的第一个类必须包含主方法。 不可以使用其它源文件中自定义的类。

    22.4.3 String类新增方法

    image.png