Java程序设计学习笔记
【期末题型】
- 单选10分 多选10分 判断10分 简答20分
- 填空(知识点、读程序写结果、补全程序)50分
第一章 Java简介
Java的历史
- Java得名于印度尼西亚爪哇岛
- 每半年更新一个版本,14年SE8,18年SE11,23年SE21,24年JDK23最新版
Java的特点
- 源程序->字节码(编译程序),运行字节码程序(解释程序),虚拟机两个程序都包括
- 字节码执行两种方式:即时编译方式、解释执行方式(一次编写,处处运行)
- Java虚拟机可以在任何处理器上安全并且兼容地执行.class文件中的字节码
- Java的特点
- 平台无关性:能在所有计算机上运行
- 面向对象:封装
- 分布式,多线程:核心技术是支持分布式通讯,特点是内置对多线程的支持,多线程允许同时完成多个任务
- 安全:运行前校验;采用沙箱运行模式;不允许访问客户端的文件系统等
- 动态:因类是动态装载;Java可在分布环境中动态维护
- 简单:语法上没有指针;垃圾收集机制;丰富的类库
Java工具包的安装与配置
- Java平台 = API + JVM -> 需要下载和安装Java软件开发工具箱(JDK)
- Java运行平台分三个版本:SE标准版,EE企业版,ME微型版
- 配置path和classpath:path添加jdk bin的安装路径,classpath添加当前路径和jdk lib的安装路径
- 配置JAVA_HOME环境变量:为了方便引用,遵循归一原则,部分第三方会引用约定好的
- JAVA_HOME变量其实就是JDK安装路径的根目录
- JDK目录下有bin、lib等子目录,bin目录保存了javac.exe、java.exe等命令文件,lib目录保存了java的类库文件
Java应用程序
- 源程序(编辑器编写)-> 字节码(编译器编译)-> 运行(载入、代码校验、解释执行)
- 每个类的入口都是它的main方法,每个Java程序必须声明一个main方法。
- 一个文件只有一个类可以是public类,且文件名必须和类名完全相同,没有public类也行文件名和某个类名相同即可
- Java常用转义字符
转义字符 | 意义 |
\a | 响铃 |
\b | 退格,将当前位置移到前一列 |
\f | 换页,将当前位置移到下页开头 |
\n | 换行,将当前位置移到下一行开头 |
\r | 回车,将当前位置移到本行开头 |
\t | 水平制表(跳到下一个tab位置) |
\v | 垂直制表 |
\\ | 代表一个反斜线字符'\' |
\' | 代表一个单引号字符 |
\" | 代表一个双引号字符 |
\0 | 空字符 |
\ddd | 1-3位八进制数所代表的任意字符 |
\xhh | 1-2位十六进制所代表的任意字符 |
- Java编程规范
- 包名:全小写,中间可以由点分隔开
- 类名:首字母大写,多个单词合成每个单词首字母都大写
- 接口名:和类名相同
- 方法名:多个单词合成,第一个单词是动词,首字母小写,中间每个首字母大写
- 变量名:全小写,一般为名词
- 常量名:基本数据类型常量名泉大些,多个单词用下划线隔开
第二章 Java的基本知识
Java标识符规则
- 标识符(identifier):对各种变量、方法和类等要素命名时使用的字符序列。
- Java标识符命名规则:
- 标识符由字母、下划线_、美元符号$和数字组成。
- 标识符不能用数字开头
- 标识符中的字母区分大小写,长度无限制
- 尽量“见名知意“且不能与Java的关键字重名
Java常用关键字
- 关键字(保留字)就是Java语言中已经被赋予特定意义的一些单词,它们在程序上有着不同的用途,不可以把关键字作为名字来用。
- 关键字一律用小写字母表示,按用途可以划分为:数据类型、语句、修饰、方法、类、接口、包,并保留了const和goto。
数据类型分类及区别
- 数据类型:
- 基本数据类型/简单数据类型:boolean, char, byte, short, int, long, float, double
- 引用数据类型:类、接口、数组
- 常量用final表示、只能使用不能修改,变量=变量名+变量类型+作用域
- 变量按照被声明的位置划分:局部变量->方法内部,成员变量->类内部方法外部(没有全局变量概念,但是public类的内部static成员变量或成员方法本质上是全局变量/全局方法,也就是每个对象都一定包含其类的static成员变量/成员方法)。
- char:2个字节16位,没有符号位,范围0~65536,用int转换
- byte:8位,short:16位,int:32位,long:64位
- Java是强类型语言,通常不允许类型替代,但提供了类型转换机制
- 不同类型混合运算,先转换为同一类型,低的转换成高的
- 赋值的时候隐性转换,低的赋给高的自动转换成高的
- 前四个同级不能自动转换需要强制类型转换,也是显式类型转换,这个只跟范围(位数)有关,比如int转long就隐性转,小范围转大范围可以自动转;但是float, double转int需要去掉小数点后所以大范围转小范围需要强制类型转换。
- float:32位,double:64位
- 运算符按功能划分:
- 赋值运算符:=,+=,-=,*=,/=,%=(赋值语句可以连一起)
- 算术运算符:+, -, +. -, *, /, %, ++, --, +(字符串相加输出全转字符)
- 关系运算符:==, !=, <, >, <=, >=, instanceof(都是boolean型)
- 逻辑运算符:&与, |或, ^异或, !非, &&与短路, ||或短路
- &和|都是按位操作,没有短路保护
- &&和||有短路保护,左边可以决定结果就不算右边了
- 位运算符:<<左移, >>算数右移, >>>无符号右移全补0
- 适用byte, short, char, int, long,低于int转换int再移
- 一个数左移n位,就等于这个数乘以2的n次方,一个数右移n位,就等于这个数除以2的n次方
- 条件运算符:?:如x?y:z,x为true结果就是y,x为false结果就是z
- 数据类型:
控制语句
- Java程序通过控制语句来执行程序流,完成一定的任务。
- Java中的控制语句有以下几类:
- 分支语句:if-else, switch
- 循环语句:while, do-while, for
- 与程序转移有关的跳转语句:break, continue, return
- 例外处理语句:try-catch-finally, throw
- 注释语句://, /**/,/** */
一维及多维数组的声明、创建、初始化
- 数组变量属于引用类型,也可以看做对象,元素相当于成员变量
- Java中并没有真正的多维数组,只有数组的数组,多维数组不一定是规则矩阵形式。
第三章 面向对象(重点)
- 面向对象的基本思想:使用对象、类、封装、继承、消息等基本概念进行程序设计,尽可能运用人类的自然思维方式。
- 类:复合数据类型,封装了对象的状态和方法,包括类声明和类体。
- 类体可以包含成员变量和成员方法两种类型的成员
- 成员变量:属性,包括静态变量、实例变量
- 成员方法:构造方法(给出初始状态)+一般方法,包括静态方法、实例方法
- 类体可以包含成员变量和成员方法两种类型的成员
- 对象:创建一个对象包括对象的声明和为对象分配成员变量两个步骤。
- 使用new运算符和类的构造方法为声明的对象分配成员变量。
- 类声明的变量/对象名属于引用类型,即该变量中存放的是对象实体的地址。
- 用成员访问运算符“.”来操作自己的变量和调用类中的方法。
- 没有实体的对象是空对象,要避免使用。“垃圾收集”机制可以释放空实体内存。
- 类变量:静态所有实例改的同一个内存空间,而且可以通过类名访问;实例变量内存空间随对象不同而不同,只能通过对象访问。
- 常量:final修饰,必须初始化(赋值就行不一定必须声明时),只能读不能写,而且不能被继承,不能重写只能赋值一次
- 方法:类的动态属性,标识类所具有的功能和操作。方法声明和方法体。
- 方法体包括变量的定义和合法的Java语句。
- 可以分为构造方法、实例方法、类方法/静态方法。
- 构造方法:类创建对象时使用的特殊的方法,在对象创建时与new一起用来分配内存,初始化对象状态。参数可有可无。
- 构造方法的名字必须与它所在类的名字完全相同
- 不返回数据类型,也不是void型
- Java允许一个类中有若干个构造方法,但是参数的个数/类型有所不同
- 如果没有显式定义会生成默认构造函数,没有参数方法体为空
- 但是如果有显式定义那不再提供缺省的构造方法即使那个是错的
- 静态初始化块:通过 static {} 定义;在类加载时执行一次;用于初始化静态变量,且只会执行一次。
- 实例初始化块:通过 {} 定义;每次创建对象时都会执行,在构造函数之前执行;用于每次创建对象时执行的初始化逻辑。
- Java对象初始化的执行顺序为:静态语句块->静态变量初始化->实例语句块/成员变量初始化->构造方法(实力语句块和成员变量初始化看谁先定义谁先执行)
- 参数传值:只传值的拷贝而且必须实例化,引用类型(对象、数组、接口)传的是引用地址而非对象本身
- 包package:包将功能类似的类放到一组,并按照类与类的关系分层分类组识;是基于树形结构的有效管理机制。
- import语句:可以引入包中的类,一个类不是public只能在其所在的包中被使用,其他包的无论如何都不能用。
- 访问控制/访问权限(可以适用于构造方法,protected不能修饰类,private一般不用于修饰外部类)
同一个类 | 同一个包 | 同一个包的子类 | 不同包的子类 | 不同包的类 | |
public | 可以 | 可以 | 可以 | 可以 | 可以 |
protected | 可以 | 可以 | 可以 | 可以 | 不可以 |
default | 可以 | 可以 | 可以 | 不可以 | 不可以 |
private | 可以 | 不可以 | 不可以 | 不可以 | 不可以 |
封装
- 封装性:把对象的属性和服务结合成一个独立的相同的单位,并尽可能隐蔽对象的内部细节,包含两个含义:
- 把对象的全部属性和全部服务结合在一起,形成一个不可分割的独立单位(即对象)
- 信息隐蔽,即尽可能隐蔽对象的内部细节,对外形成一个边界,只保留有限的对外接口使之与外部发生联系。
继承
- 继承性:类继承是子类继承父类的成员变量和方法作为自己的成员变量和方法。
- 继承是一种由已有的类创建新类的机制。由继承而得到的类称为子类,被继承的类称为父类(超类)。
- 特点(用extends来声明一个类是另一个类的子类)
- 利用继承可以有效实现代码的重用,子类只需添加新的功能代码
- 父类可以是Java库中的类,也可以是自己编写的类
- Java不支持多重继承,即子类只能有一个父类
- 子类和父类的继承性
- 在同一包中:除了private都继承,继承过来后访问权限不变
- 不在同一包:继承public和protected,继承过来后访问权限不变
- 子类对象的构造过程:先调用父类的某个构造方法,如果没指名用哪个就调用不带参数的那个构造方法。内存分配是所有都分配,只是有的没权限看而已,也就是继承过程由内存浪费。
- 变量或者方法重名重写的话,有重复的调用子类新写的,没有的话用父类的
- 上转型对象:子类对象赋值给父类对象。不能操作子类新增的方法和成员变量,可以操作子类继承的、隐藏的成员变量,也可以使用子类继承的、覆盖的方法(用的是子类新写的,调用的时候通知子类对象调用)。
多态/动态绑定
- 多态性:一般类中定义的属性或服务被特殊类继承之后,可以具有不同的数据类型或表现出不同的行为。
- 多态:指一个程序中同名的不同方法共存的情况;或同名方法的调用,实现了不同的功能。
- 两种形式:
- 类继承时的方法重写(或方法的覆盖)
- 同一类中方法重载
- 继承下的多态性:父类的某个方法被其子类覆盖时,可以产生自己的功能行为,即同一个操作被不同类型对象调用时可能产生不同的行为。上转型对象有多种形态。
- 继承时多态存在的3个条件:继承关系;子类都重写某方法;父类引用指向子类
- 两种形式:
- 动态绑定:实际new的是哪个对象就调用哪个对象的方法。对于父类的方法中有一个指针指向它的方法,当new出一个子类对象时,这个指针会指向子类的方法)
- 类和对象在Java虚拟机中的存放方式:
- 嵌套类
- 静态嵌套类和内部类(普通的内部类、局部内部类、匿名内部类)
- 内部类可以声明为private或者protected,不能单独存在,可以直接访问外层类成员
- 内部类出现命名冲突可以用外层类名.this来访问外层类对象的成员
- 匿名类:使用类创建对象时程序允许把类体与对象的创建组合在一起。包含构造方法和类体两部分、无类名,匿名类一定是内部类。可访问外嵌类的成员变量和方法,不可声明static成员变量和static方法。也可以是接口名和类体创建一个匿名对象,此类体被认为是实现了接口的类去掉类声明后的类体。
- Lambda表达式:一种匿名方法,使用它可以简化函数式接口的编写,使代码更简洁。语法格式:
(类型1 参数1, 类型2 参数2, ...)->{方法体}
- 编译器对待Lambda表达式如同它是一个从匿名内部类创建的对象。
- 函数式接口
- 函数式接口指只包含一个抽象方法的接口,因此也称为单抽象方法接口。
- 每一个Lambda表达式都对应一个函数式接口,可以将Lambda表达式看作实现函数式接口的匿名内部类的一个对象。
- Lambda表达式可以作为参数传递给方法,将可执行代码作为参数传递给方法,参数必须是兼容的函数式接口类型
- 方法引用(双冒号)
- 对象名::实例方法名
- 类名::静态方法名
- 类名::实例方法名
- 类名::new
- 方法引用不是方法调用,所以右侧没有圆括号,有重载根据参数个数判断用哪个,引用构造方法双冒号右侧只能是new
抽象类
- 抽象方法:定义Java方法时可以只给出方法头,而不必给出方法体,即方法实现的细节,这样的方法被称为抽象方法,必须用abstract修饰,没有{}。
- 抽象类:包含抽象方法的类必须声明为抽象类,用abstract修饰。
- 不能用new直接创建对象,必须产生子类由子类创建对象。
- 只关心有没有不关心怎么实现的,具体实现由子类负责
- 子类必须实现也就是覆盖所有抽象方法,不然子类也只能是抽象类
接口
- Java接口是用来实现多重继承功能,它相当于一种特殊的抽象类;这种抽象类只包含常量和方法的定义,没有变量和方法的实现;接口的使用提高软件开发和维护的效率。
- interface 接口的名字 声明,接口体只进行方法声明不允许实现,没有方法体{},且用;结尾
- 使用的时候用implements声明自己实现一个或多个接口(逗号隔开)
- 如果使用接口必须实现所有方法
- 接口方法默认public和abstract,这部分修饰符可以省略,但实现的时候必须用public来修饰
- 父类直接实现接口子类不必显式使用implements声明
- 接口之间也可以继承,子接口继承父接口中全部方法和常量
- 接口的回调
- 接口回调:可以把使用某一接口的类创建的对象引用赋给该接口声明的接口变量(接口类的对象),该接口变量就可以调用被类实现的接口方法。这一过程称作对象功能的接口回调。
- 接口做参数:当一个方法的参数是一个接口类型时,如果一个类实现了该接口,那么就可以把该类的实例的引用传值给该参数。进而,参数可以回调实现该类的接口方法。
super,this,final
- this关键字:this代表调用成员方法的当前对象
- 使用:构造方法、实例方法;类方法不能用this
- 局部变量跟类变量撞名字的话this用的是局部变量
- super关键字:两种用法,一种是子类使用super调用被子类隐藏的成员变量和方法,另一种是子类使用super调用父类的构造方法。
- final关键字:不能被继承,方法不能被重写,变量只能赋值一次(声明同时或构造方法中显式肤质才能使用)。不允许修饰构造方法、抽象类、以及抽象方法。
枚举类型
- 枚举类型enum:使用一组常量值来表示特定的数据集合,该集合中数据的数目确定,且这些数据能取预先定义的值。
- 每个枚举类型的成员都可以看作是enum类的实例,默认被final public static修饰。
- 用“枚举名.枚举成员”来调用,或者“枚举名.valueOf()”的形式进行调用。
方法重载
- 方法重载:一个类中可有多个方法具有相同的名字,但这些方法的参数必须不同(即或者是参数的个数不同,或者是参数的类型不同,或者是排列顺序不同)
- 特点:方法的返回类型和参数的名字不参与比较,即与方法返回值和形参名无关。
- 功能多态性:向功能传递不同的消息,一边对象根据消息产生一定的行为。
异常处理
- 注解(annotation):元数据,描述数据的数据。在编译、类加载、运行时被读取并执行相应的处理。@注解名
- 基本注解:@Deprecated @SuppressWarnings @SafeVarargs @FunctionalInterfacce
- 元注解:@Target @Retention @Document @Inherited @Repeatable
- 自定义注解:@interface 注解名
- 反射(Reflection):程序在运行状态中,可以动态获取程序信息以及动态调用对象的功能。
- Class类:反射机制的基础
常用方法 | 功能说明 |
public Package getPackage() | 返回类的存放路径 |
public static Class<> forName(String className) | 返回className对应的类 |
public Annotation[] getAnnotations() | 以数组形式返回所有注解 |
public Constructor<>[] getConstructors() | 返回类的所有public构造方法 |
public Filed[] getDeclaredFields() | 返回类的所有成员变量 |
public Method[] getDeclaredMethod() | 返回类的所有成员方法 |
...... |
- 异常类
- 异常处理机理:异常类Exception相应子类创建一个异常对象,封装信息提交系统,称为抛出异常throw,接收到后会找代码并处理异常叫捕获异常catch。
- try部分有异常立刻停止执行,转向执行相应catch部分,catch语句中声明的异常对象封装了异常事件发生的信息,finally语句提供统一出口,对程序状态作统一管理。异不异常finally都要执行,一般是资源的清除工作。
- 受控异常和非受控异常
- 受控异常(编译时异常, checked exception):是指编译器要求必须处置的异常,即程序在运行时由于外界因素造成的一般性异常。编译器要求java程序必须捕获或声明所有编译时异常。对于这类异常,如果程序不处理,java 程序将无法编译通过。
- 非受控异常(运行时异常, unchecked exception):是指编译器不要求强制处置的异常,一般是指编程时的逻辑错误,是程序员应该积极避免其出现异常。
- 自定义异常类:可以扩展Exception类定义自己的异常类,然后规定哪些方法可能产生这样的异常。首先继承并声明,throws语句声明可能抛出的异常。
- 受控异常和非受控异常
第四章 范型与容器类
范型方法/泛型类
- 泛型实质就是将数据的类型参数化,通过为类、接口、方法以及变量设置类型参数来定义泛型。
- 定义语法:使用类型参数<T>来定义类、接口、方法以及变量,具体如下:
- 泛型类:[修饰符]class 类名<T>
- 泛型接口:[修饰符]interface 接口名<T>
- 泛型方法:[修饰符][static]<T> 返回值类型 方法名(T参数)
- 泛型变量:[修饰符]<T>变量名
- 泛型实例化时可以根据不同的需求给出类型参数T的具体类型。
- 参数名不能重复,可以被重载,找最近共同父类,类型参数T只能是引用类型不能是基本类型。
- 擦除:翻译字节码默认用Object类来替换类型参数。
- 类型参数的上界
- 在定义泛型时,可以直接对类型参数做出限制,其语法如下:<T extends anyClass>
- 类型参数T必须是以下几种类型之一:anyClass类、anyClass的子类、实现了anyClass接口的类。
- 在定义泛型时,可以直接对类型参数做出限制,其语法如下:<T extends anyClass>
- 类型通配符:在创建泛型类对象时,使用通配符"?"可以限制该泛型类的类型范围。语法如下
- 泛型类名 <?entends anyClass>:anyClass或其子类或实现其接口的类
- 泛型类名 <?super anyClass>:anyClass或其超类或其接口上层接口的类
- 泛型类名 <?>:类型参数无限制
- 泛型类或接口可被继承与实现
各种容器类的使用(List,ArrayList,LikedList,Set,HashSet,TreeSet,Map,HashMap,TreeMap)
- 容器类:Java以类库的形式供用户开发程序时可以直接使用的各种数据结构。
接口 | 描述 |
Collection | 容器层次中的根接口 |
Set | 集合 |
List | 序列 |
Map | 映射 |
Queue | 队列 |
- Collection接口:不能直接使用,但提供了添加元素、删除元素、管理数据的方法
- List列表接口:Collection自接口,包含有序元素的线性表,必须按顺序且可重复可置空。两种实现:链表LinkedList、顺序表ArrayList。
- Set集合接口:没顺序但不能重复,元素顺序与加入顺序无关。实现Set接口的两个主要类是HashSet哈希集合、TreeSet树集合。
- Map映射接口:元素成对出现,提供键key到值value的映射。常用的实现类为HashMap<K,V>和TreeMap<K,V>。允许空。
Object
- Object类是所有Java类的根基类(父类)。
- 没有extends指明其基类则默认基类为Object类
- clone创建并返回副本,equals判断是否相等(看的是封装后对象的类型+数据),toString返回字符串表示,hashCode返回哈希码值,wait当前线程等待,notify唤醒在此对象监视器上等待的单个线程,notifyAll唤醒在此对象监视器上等待的所有线程。
- 注意字符串字面量优化,声明时初始化的有重复的话直接指向已有的。
string
- Java使用java.lang包中的String类来创建一个字符串变量,因此字符串变量是类型变量,是一个对象。字符串是不可更改的。
- compareTo比较大小,相同返回0,当前大为正当前小为负
- indexOf找到首次出现s的位置,没找到返回-1
- split按照指定的分隔符分隔,返回分隔后的字符串数组
- 与基本数据类型的转化parseInt等
- static String valueOf 数字转化字符串
- toCharArray开长度相等的字符数组并把字符串对象全部字符复制到该数组
- getBytes转化为字节数组,可以用length顺便求字节数
stringbuffer
- 硬要改string的话就重新开空间了,所以StringBuffer类能创建可修改的字符串序列。
- 三个构造方法
- StringBuffer():初始16个字符,自动调整容量不够就加
- StringBuffer(int size):指定初始容量不够也能自动加
- StringBuffer(String s):初始容量是s长度加16个字符
- 常用方法
- append追加对象
- charAt(int n)得到n位置上的单个字符,从0开始的
- setCharAt(int n,char ch)把n位置换成ch
- insert(int index, String str)一个字符串插入另一个字符串,返回当前对象引用
- reverse()字符翻转并返回当前对象引用。
- delete(int startIndex, int endIndex):删除从开始到结束-1位置的子字符串。
- ensureCapacity(int minimumCapacity)确保容量至少等于指定的最小值。
- StringBuffer是线程安全的,StringBuilder不是线程安全的。
简单的正则表达式
- 正则表达式(regular expression)描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。
第五章 图形用户界面
- JavaFX中构建图形用户界面的各种元素称为节点(Node),主要分成三类:
- 面板类(pane class):作为各种控件和形状的容器。
- 控件类(control class):完成与用户的交互。与面板类不同的是,控件里面不能再包含其他控件。
- 辅助类(helper class):用于描述控件的属性,例如颜色类Color、字体类Font、图像类Image和图像显示类ImageView等。
- JavaFX程序都要继承抽象类javafx.application,需要重写start方法用于将控件放入场景中并在舞台中显示场景。
- 舞台Stage:显示场景的窗口
- 场景Scene:舞台中的对象
- 节点Node:可视化的组建,所有节点构成一个树状结构的场景图
了解fxml文件和程序各部分的关系
- Controller 类:FXML 文件通常会和一个 Java 控制器类(Controller Class)相关联。这个控制器类负责处理 UI 组件的逻辑和事件,控制器类中的字段和方法与 FXML 文件中的控件和元素相关联。控制器类的字段和方法通过 @FXML 注解与 FXML 中的元素绑定。
了解javafx.application、javafx.stage、javafx.scene关系
- javafx.application.Application
- Application 类是 JavaFX 程序的 入口类,它负责启动和控制 JavaFX 应用程序的生命周期。
- launch() 方法是 JavaFX 应用的启动方法,它会自动调用 start() 方法,这个方法是应用程序的 主入口,在这里你可以设置应用程序的主界面、窗口等。
- javafx.stage.Stage
- Stage 是 JavaFX 应用程序的窗口,每个 Stage 对象表示一个应用的窗口。
- primaryStage 是应用程序启动时由 Application 提供的 主窗口,通常用于设置应用的 主界面。
- Stage 可以有多个场景(Scene),每个场景对应一个不同的界面,可以动态切换。
- javafx.scene.Scene
- Scene 是 JavaFX 应用程序中的 用户界面容器,它包含了所有显示的 UI 元素(如按钮、文本框、布局等)。
- 每个窗口(Stage)都需要一个场景(Scene),并且每个场景都可以有不同的 UI 组件。
- Scene 可以通过 setRoot() 方法来设置根元素,并通过 布局管理器 来排列各个控件(如 VBox、HBox、BorderPane 等)。
第六章 IO流和JBC
熟悉IO流分类
- I/O流中的输入流的指向称作源,程序从指向源的输入流中读取源中的数据;输出流的指向称作目的地,程序通过输出流写入数据把信息传递到目的地。
- 分类
- 数据流动方向:输入流(InputStream) 和输出流(Output Stream)
- 关联的是源还是流:节点流(Node Stream) 和 处理流 (Processing Stream)
- “颗粒大小”:字符流(CharacterStream) 和 字节流 (Byte Stream)
- I/O流的顶层基类
- InputStream:抽象类java.io.InputStream,字节输入类类型父类
- OutputStream:抽象类java.io.OutputStream,字节输出类类型父类
- Reader:字符输入流类型父类
- Writer:字符输出流类型父类
- 常用I/O流类型
能写程序完成基本的文本文件读写
了解File类
- java.io.File类代表系统文件名(路径和文件名),构造方法参数可以是一或两个路径
对象序列化
- 串行化:对象的寿命通常随着生成该对象的程序的终止而终止。有时候,可能需要将对象的状态保存下来,在需要时再将对象恢复。我们把对象的这种能记录自己的状态以便将来再生的能力,叫做对象的持续性(persistence)。对象通过写出描述自己状态的数值来记录自己,这个过程叫对象的串行化(Serialization)。
- 目的:写出对象的状态信息,并遍历该对象对其他对象的引用,递归的序列化所有被引用的其他对象,从而建立一个完整的序列化流。
- 必须实现以下两个接口之一:java.io.Serializable/java.io.Externalizable
- 定义一个可串行化对像,构造对象的输入/输出流
- 只能保存对象的非静态成员变量,不能保存成员方法和静态成员变量,而且只保存值,修饰符都不保存
- transient关键字标明状态瞬时的一些对象
熟悉JDBC链接的几个关键步骤和相关类
- JDBC(Java Database Connectivity)是在Java程序中访问数据库的一组标准API,是Java数据库应用程序开发中的一项核心技术。
- 使用JDBC访问数据库的基本步骤为
- 加载驱动程序java.lang.Class.forName(JdbcDriverClass)
- 建立与数据库的链接/创建数据连接对象 Connection conn = DriverManager.getConnection(String url, String user, String password)
- 创建执行方式语句
- 执行SQL语句(创建Statement接口对象Statement st = conn.createStatement();,调用该对象相应方法将SQL语句发送到数据库并执行)
- 处理返回结果和关闭创建的各种对象(关闭次序是结果集对象->Statement对象->数据库连接对象)
- Java程序通过JDBC调用存储过程
- 首先在DBMS中定义存储过程
- 创建CallableStatement对象
第七章 线程
- Java中的线程
- 线程是比进程更小的执行单位。一个进程在其执行过程中,可以产生多个线程,形成多条执行线索,每条线索,即每个线程也有它自身的产生、存在和消亡的过程,也是一个动态的概念。
熟悉线程的生命周期
- 由Thread类及其子类创建的对象称作线程,新建的线程在它的一个完整生命周期中通常要经历4种状态
- 新建:已经有相应的硬件资源
- 运行:start()通知JVM,排到之后run()
- 中断:有四种原因的中断
- JVM把CPU资源切换给其他线程,本线程让出CPU的使用权
- 执行了sleep(int millsecond)进入休眠状态,过了那些时间重新排队
- 执行了wait()进入等待状态,不排队等其他notify()叫它才再去排队
- 进入阻塞状态,不能重新排队,阻塞原因消除了重排队,在中断点继续
- 死亡:结束了run方法/强制run方法结束,释放实体/释放线程对象的内存
能写多线程的程序
能写程序实现线程同步程序
- 线程同步是指:多个线程要执行一个synchronized修饰的方法。如果一个线程A占有CPU资源期间,使得synchronized方法被调用执行,那么该synchronized方法返回之前,其他占有CPU资源的线程一旦调用这个synchronized方法就会引起堵塞,堵塞的线程要一直等到堵塞的原因消除,再排队等待CPU资源,以便使用这个同步方法。
- synchronized的三种使用方式:
- 修饰实例方法:作用于当前实例加锁
- 修饰静态方法:作用于当前类对象加锁
- 修饰代码块:指定加锁对象,对给定对象加锁。
能写生产者、消费者程序
- Produce线程生产数据并放入公共缓冲区
- Consumer线程从缓冲区读数据
- 二者应同步
Runnable
Thread
- 在Java语言中,用Thread类或子类创建线程对象。
- 用户可以扩展Thread类,但需要重写父类的run方法,其目的是规定线程的具体操作,否则线程什么也不做,因为父类的run方法中没有任何操作语句。
线程池
- Executor 接口
- 创建和管理一组线程(线程池)
- execute方法启动线程
- ExecutorService 接口
- Executor的子接口,声明一些其他方法管理Executor的生命周期
- 用Executors的静态方法调用
- shutdown 方法在任务结束后终止线程
- Executors 类
- newFixedThreadPool 创建固定个线程的线程池
- newCachedThreadPool创建需要个数线程的线程池
第八章 网络编程
套接字Socket
- 服务器建立ServerSocket对象ServerSocket(int port)
- 当服务器端的ServerSocket对象接收到了客户端的套接字连接请求后,就可以使用accept()方法接受该请求。所谓“接收”客户端的套接字请求,就是accept()方法会返回一个Socket对象,称作服务器端的套接字对象。
- 客户端创建Socket对象Socket(String host, int port)
- 也可以使用不带参数的构造方法Socket()先创建客户端的套接字对象,再调用connect(SocketAddress endpoint)方法,与参数SocketAddress指定的服务器端套接字建立连接。
- 流连接
- 服务器端的Socket对象使用getOutputStream()方法获得输出流(指向客户端Socket调用getInputStream()方法获得的输入流);
- 服务器端的Socket对象使用getInputStream()方法获得输入流(指向客户端Socket对象调用getOutputStream()方法获得的输出流)。
UDP数据报
广播数据报
第九章 Lambdas和Streams
什么是函数式接口
- 定义:函数式接口是一个只包含 一个抽象方法 的接口,可以包含多个 默认方法 和 静态方法。这样的接口可以作为 Lambda 表达式的类型。
- 作用:函数式接口是 Lambda 表达式和方法引用的基础,Java 8 引入了对函数式编程的支持,允许使用 Lambda 表达式简洁地实现接口。
熟悉lambdas表达式的常用写法
熟悉IntStream、Stream<T>常用方法