java基础

Java

Java

Java SE

Java ME

Java EE

开发Java三个步骤

编写代码

编译代码

运行代码

JDK

JRE

JVM
核心类库

开发工具

关键字

关键字的字母全部小写

class
定义一个类 后面接类名
main
程序执行的入口点
常量
字符串常量
整数常量
小数常量
字符常量
布尔常量
空常量
变量
定义格式 数据类型 变量名 = 数据值;
占用内存
整数

####### byte

######## 1

####### short

######## 2

####### int

######## 4

####### long

######## 8

浮点数

####### float (单精度)

######## 4

####### double(双精度)

######## 8

字符

####### char

######## 2

布尔

####### boolean

######## 1

数据类型
基本数据类型

####### 数值型

######## 整数(byte,short,int,long)

######## 浮点数(float,double)

######## 字符(char)

####### 非数值型

######## 布尔(boolean)

引用数据类型

####### 类(class)

####### 接口(interface)

####### 数组([])

类型转换
取值范围小的数据可以直接给取值范围大的类型赋值

####### double

######## float

######### long

########## int

########### short

############ byte

########### char

强制转换

####### 目标数据类型 变量名 = (目标数据类型) 值或变量

private
权限修饰符 保护成员不被别的类使用
修饰成员变量
修饰成员方法
this
修饰的变量用于指代成员变量
解决局部变量隐藏成员变量
方法被哪个对象调用 this就代表哪个对象
super
代表父类存储空间的标识(可以理解为父类对象引用)
package 包名; (多级包用.分开)
对类进行分类管理
import 包名
导包
关键字的字母全部小写

标识符

有数字、字母、下划线和美元符号组成

小驼峰命名法

方法、变量

大驼峰命名法

运算符

+ - * / %

++ –
++在前变量会直接改变自身数值
++在后 先提取出变量值 下一行再进行自增运算
= += -= *= /= %=
== != > >= < <=
& | ^ ! && ||
关系表达式?表达式1:表达式2;

分支语句

if语句

if(…){

}

if(…){

}else{
}

if(…){

}else if(…){
}

else{
}

switch

switch(){

case1:
…;
break;
case2:
…;
break;
default:
…;
break;
}

循环语句

先判断后执行

for
适合循环次数已知
while
适合循环次数未知

先执行后判断

do while

跳转控制语句

continue
跳过某次循环体的执行
break
终止循环体

修饰符

权限修饰符

private
默认
protected
public

状态修饰符

final
修饰方法:表明该方法是最终方法,不能被重写
修饰变量:表明该变量是常量,不能再次被赋值
修饰类:表明该类是最终类,不能被继承
final修饰局部变量
基本类型:final 修饰指的是基本类型的数据值不能发生改变
引用类型:final 修饰指的是引用类型的地址值不能发生改变,但是地址里面的内容是可以发生改变的
static
是静态的意思,可以修饰成员方法,成员变量
被类的所有对象共享
推荐使用类名调用
静态成员方法只能访问静态成员
非静态的成员方法

####### 能访问静态的成员变量
能访问非静态的成员变量
能访问静态的成员方法
能访问非静态的成员方法

静态的成员方法

####### 能访问静态的成员变量
能访问静态的成员方法

字符串

String

Java程序中 所有的双引号字符串 都是String类的对象
底层逻辑是byte[]
方法
构造方法
String s = “ XXX ”;
使用equals()方法进行比较
s1.equals(s2);
line.charAt(i)
字符串遍历
public static String valueOf(int i)
返回 int 参数的字符串表示形式
split
把字符串按某种规律 或“,”或“ ”将数据分开

StringBuilder

是一个可变的字符串类 可以看作是一个容器
方法
添加方法
append
反转方法
reverse
转换
toString

转换

String s = sb.toString();
StringBuilder sb = new StringBuilder(s);

数组

用于存储多个相同类型数据的存储模型

数据类型 [] 变量名

初始化

动态初始化
数据类型[] 变量名 = new 数据类型[数组长度];
静态初始化
数据类型[] 变量名 = {数据1,数据2,数据3…};

数组元素访问

数组名[索引]

赋值

数据类型[索引] = 数值;

常见操作

遍历
获取数组元素数量 数组名.length
获取最值

集合

提供一个存储空间可变的存储模型,存储的数据容量可以发生改变

集合分类

单列
Collection

接口

可重复

####### List
接口

######## ArrayList
实现类

######## LinkedList
实现类

不可重复

####### Set
接口

######## HashSet
实现类

######## TreeSet
实现类

双列
Map

接口

不可重复

####### HashMap
实现类

增强for循环

简化数组和Collection集合的遍历

格式:

for(元素数据类型 变量名 : 数组或者Collection集合)
{
//在此处使用变量即可,该变量就是元素
}

Collection

单例集合的顶层接口

概述
是单例集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素
JDK 不提供此接口的任何直接实现,它提供更具体的子接口(如Set和List)实现
用多态的方式实现
方法
boolean add(E e)
添加元素
boolean remove(Object o)
从集合中移除指定的元素
void clear()
清空集合中的元素
boolean contains(Object o)
判断集合中是否存在指定的元素
boolean isEmpty()
判断集合是否为空
int size()
集合的长度,也就是集合中元素的个数
Iterator iterator()

集合特有迭代器

返回此集合中元素的迭代器,通过集合的iterator()方法得到
常用方法
E next():返回迭代中的下一个元素
booleanhasNext():如果迭代具有更多元素,则返回

true

Iterator it = c.iterator();

while(it.hasNext()){
String s = it.next();
System.out.println(s);
}

List

序列

有序集合(也称为序列),用户可以精确控制列表中每个元素的插入位置。用户可以通过整数索引访问元素,并搜索列表中的元素
特点
有序:存储和取出的元素顺序一致
可重复:存储的元素可以重复
方法
void add(int index,E element)
在此集合中的指定位置插入指定的元素
E remove(int index)
删除指定索引处的元素,返回被删除的元素
E set(int index,E element)
修改指定索引处的元素,返回被修改的元素
E get(int index)
返回指定索引处的元素
ListIterator

列表迭代器

通过List集合的listIterator​()方法得到,所以说它是List集合特有的迭代器
方法
E next():返回迭代中的下一个元素
boolean hasNext():如果迭代具有更多元素,则返回 true
E previous​():返回列表中的上一个元素
boolean hasPrevious​():如果此列表迭代器在相反方向遍历列表时具有更多元素,则返回 true
void add​(E e):将指定的元素插入列表

ArrayList

底层数据结构是数组,查询快,增删慢

可调整大小的数组实现
方法
构造方法
public ArrayList();
添加方法
boolean add (E e)

将指定的元素追加到此列表的末尾。

void add (int index, E element)

在此列表中的指定位置插入指定的元素。

常用方法
public boolean remove(Object o)

删除指定的元素,返回删除是否成功

public E remove(int index)

删除指定索引处的元素,返回被删除的元素

public E set(intindex,E element)

修改指定索引处的元素,返回被修改的元素

public E get(int index)

返回指定索引处的元素

public E get(int index)

返回指定索引处的元素

public int size()

返回集合中的元素的个数

特有方法
public void addFirst​(E e)

####### 在该列表开头插入指定的元素

public void addLast​(E e)

####### 将指定的元素追加到此列表的末尾

public E getFirst​()

####### 返回此列表中的第一个元素

public E getLast​()

####### 返回此列表中的最后一个元素

public E removeFirst​()

####### 从此列表中删除并返回第一个元素

public E removeLast​()

####### 从此列表中删除并返回最后一个元素

LinkedList

底层数据结构是链表,查询慢,增删快

set集合

特点
没有带索引的方法,所以不能使用普通for循环遍历
不包含重复元素的集合

hashSet

元素不重复
顺序不一定一致

特点
底层数据结构是哈希表
对集合的迭代顺序不作任何保证,也就是说不保证存储和取出的元素顺序一致
没有带索引的方法,所以不能使用普通for循环遍历
由于是Set集合,所以是不包含重复元素的集合
保证元素唯一性源码分析
要保证元素唯一性,需要重写hashCode()和equals()

LinkedHashSet

元素不重复
顺序一致

特点
哈希表和链表实现的Set接口,具有可预测的迭代次序
由链表保证元素有序,也就是说元素的存储和取出顺序是一致的
由哈希表保证元素唯一,也就是说没有重复的元素

TreeSet

元素不重复
自然排序

特点
元素有序,这里的顺序不是指存储和取出的顺序,而是按照一定的规则进行排序,具体排序方式取决于构造方法
TreeSet​():根据其元素的自然排序进行排序
TreeSet​(Comparator comparator) :根据指定的比较器进行排序
没有带索引的方法,所以不能使用普通for循环遍历
由于是Set集合,所以不包含重复元素的集合

Map

键值对集合

Interface Map<K,V> K:键的类型;V:值的类型
将键映射到值的对象;不能包含重复的键;每个键可以映射到最多一个值
创建对象
多态的方式
具体的实现类HashMap
添加对象
用put进行添加 第一次put是添加 第二次put是修改
方法
V put(K key,V value)
添加元素
V remove(Object key)
根据键删除键值对元素
void clear()
移除所有的键值对元素
boolean containsKey(Object key)
判断集合是否包含指定的键
boolean containsValue(Object value)
判断集合是否包含指定的值
boolean isEmpty()
判断集合是否为空
int size()
集合的长度,也就是集合中键值对的个数
V get(Object key)
根据键获取值
Set keySet()
获取所有键的集合
Collection values()
获取所有值的集合
Set<Map.Entry<K,V>> entrySet()
获取所有键值对对象的集合
用Alt + Insert 重写hashCode()和equals()方法保证键重复就直接覆盖

Properties

可以保存到流中或从流中加载

属性列表中的每个键及其对应的值都是一个字符串
特有方法
Object setProperty​(String key, String value) 设置集合的键和值,都是String类型,底层调用 Hashtable方法 put
String getProperty​(String key) 使用此属性列表中指定的键搜索属性
Set stringPropertyNames​() 从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串
和IO流结合的方法
void load​(InputStream inStream) 从输入字节流读取属性列表(键和元素对)
void load​(Reader reader) 从输入字符流读取属性列表(键和元素对)(推荐)
void store​(OutputStream out, String comments) 将此属性列表(键和元素对)写入此 Properties表中,以适合于使用 load(InputStream)方法的格式写入输出字节流
void store​(Writer writer, String comments) 将此属性列表(键和元素对)写入此 Properties表中,以适合使用 load(Reader)方法的格式写入输出字符流(推荐)

哈希值

JDK根据对象的地址或者字符串或者数字算出来的int类型的数值
public int hashCode​():返回对象的哈希码值
特点
同一个对象多次调用hashCode()方法返回的哈希值是相同的
默认情况下,不同对象的哈希值是不同的。而重写hashCode()方法,可以实现让不同对象的哈希值相同

Comparable

自然排序

用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的
自然排序,就是让元素所属的类实现Comparable接口,重写compareTo​(T o)方法
重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写

Comparator

比较器排序

用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的
比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写compare​(T o1,T o2)方法
重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写

Collections

针对集合操作的工具类

概述
由静态方法组成
是针对集合操作的工具类
方法
public static <T extends Comparable<? super T>> void sort​(List list):将指定的列表按升序排序
public static void reverse​(List<?> list):反转指定列表中元素的顺序
public static void shuffle​(List<?> list):使用默认的随机源随机排列指定的列表

Stream流

Stream流把真正的函数式编程风格引入到Java中

Stream流的使用

生成流
通过数据源(集合,数组等)生成流
常见生成方式
Collection体系的集合可以使用默认方法stream​()生成流

####### default Stream stream​()

Map体系的集合间接的生成流

####### 键.stream 生成流

####### 值.stream 生成流

####### 键值对.stream 生成流

数组可以通过Stream接口的静态方法of​(T… values)生成流
中间操作
一个流后面可以跟随零个或多个中间操作,其目的主要是打开流,做出某种程度的数据过滤/映射,然后返回一个新的流,交给下一个操作使用
Stream filter​(Predicate predicate):用于对流中的数据进行过滤
Predicate接口中的方法 boolean test​(T t):对给定的参数进行判断,返回一个布尔值
Stream limit​(long maxSize):返回此流中的元素组成的流,截取前指定参数个数的数据
Stream skip​(long n):跳过指定参数个数的数据,返回由该流的剩余元素组成的流
static Stream concat​(Stream a, Stream b):合并a和b两个流为一个流
Stream distinct​():返回由该流的不同元素(根据Object.equals(Object) )组成的流
Stream sorted​():返回由此流的元素组成的流,根据自然顺序排序
Stream sorted​(Comparator comparator):返回由该流的元素组成的流,根据提供的Comparator进行排序
Stream map​(Function mapper):返回由给定函数应用于此流的元素的结果组成的流
Function接口中的方法 R apply​(T t)
IntStream mapToInt​(ToIntFunction mapper):返回一个IntStream其中包含将给定函数应用于此流的元素的结果
IntStream:表示原始 int 流
ToIntFunction接口中的方法 int applyAsInt​(T value)
mapToInt 相较于 map 有自己的特殊方法 比如sum
终结操作
一个流只能有一个终结操作,当这个操作执行后,流就被使用“光”了,无法再被操作。所以这必定是流的最后一个操作
void forEach​(Consumer action):对此流的每个元素执行操作
Consumer接口中的方法 void accept​(T t):对给定的参数执行此操作
long count​():返回此流中的元素数
收集操作
Stream流的收集方法
R collect​(Collector collector)
但是这个收集方法的参数是一个Collector 接口
工具类Collectors提供了具体的收集方式
public static Collector toList​():把元素收集到List集合中
public static Collector toSet​():把元素收集到Set集合中
public static Collector toMap​(Function keyMapper,Function valueMapper):把元素收集到Map集合中

数据结构

数据结构是计算机存储、组织数据的方式。是指相互之间存在一种或多种特定关系的数据元素的集合

通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率

数据进入栈模型的过程称为:压/进栈
数据离开栈模型的过程称为:弹/出栈
栈是一种数据先进后出的模型

队列

数据从后端进入队列模型的过程称为:入队列
数据从前端离开队列模型的过程称为:出队列
队列是一种数据先进先出的模型

数组

数组是一种查询快,增删慢的模型
查询数据通过索引定位,查询任意数据耗时相同,查询效率高
删除数据时,要将原始数据删除,同时后面每个数据前移,删除效率低
添加数据时,添加位置后的每个数据后移,再添加元素,添加效率极低

链表

链表是一种增删快的模型(对比数组)
链表是一种查询慢的模型(对比数组

哈希表

JDK8之前,底层采用数组+链表实现,可以说是一个元素为链表的数组
JDK8以后,在长度比较长的时候,底层实现了优化

方法

方法定义

标准
public static void 方法名 {

}

方法调用

####### 方法名();

带参
public static void 方法名 (数据类型 变量名){

}

方法调用

####### 方法名(参数);

带返回值
public static 数据类型 方法名(参数){

return 数据;
}

方法调用

####### 数据类型 变量名 = 方法名(参数);

通用格式
public static 返回值类型 方法名(参数){

方法体;
return 数据;
}

方法调用

####### viod 直接调用
非void 用变量接收调用

参数

实参
形参
类名
需要的是该类的对象
抽象类名
需要的是该抽象类的子类对象
接口名
需要的是该接口的实现类对象

返回值

类名
返回的是该类的对象
抽象类名
返回的是该抽象类的子类对象
接口名
返回的是该接口的实现类对象

两个明确

明确返回值类型
明确参数

方法重载

方法重写

子类中出现了和父类中一模一样的方法声明
当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容
私有方法不能被重写
子类方法访问权限不能更低(public > 默认 > 私有)

debug

加断点

运行加断点的程序

删除断点

面向对象基础

类是对象的数据类型
类是具有相同属性和相同行为的一组对象的集合
属性 成员变量
类中方法外的变量
构造方法
一种特殊的方法

####### 作用是创建对象

功能是完成对象数据的初始化
行为 成员方法
与方法相比 去掉了static
局部变量
方法中的变量
定义
定义类
public class 类名{}
创建对象
类名 对象名 = new 类名();

####### 对象名.变量名

####### 对象名.方法名()

构造方法
修饰符 类名(参数){}
标准类制作
成员变量
用private修饰
构造方法
无参/带参
成员方法
get()/set()
show()
创建对象并为其成员变量赋值
无参构造方法用set赋值
带参构造方法直接创建带有属性值的对象

面向对象三大特征

封装
客观世界里成员变量都是隐藏在对象内部
用private修饰的成员变量 设定get/set方法
继承
使得子类具有父类的属性和方法,还可以在子类中重新定义,追加属性和方法
格式
public class 子类名 extends父类名 { }
特点
子类可以有父类的内容

子类还可以有自己特有的内容

好处
提高了代码的复用性(多个类相同的成员可以放到同一个类中)

提高了代码的维护性(如果方法的代码需要修改,修改一处即可)

弊端
继承让类与类之间产生了关系,类的耦合性增强了,当父类发生变化时子类实现也不得不跟着变化,削弱了子类的独立性
在 b is a 的情况下用 避免滥用
只支持单继承
多态
同一个对象,在不同时刻表现出来的不同形态
前提和体现
有继承/实现关系

有方法重写
有父类引用指向子类对象

分类
具体类多态
抽象类多态
接口多态
访问特点
成员变量:编译看左边,执行看左边

成员方法:编译看左边,执行看右边

好处
提高了程序的扩展性

具体体现:定义方法的时候,使用父类型作为参数,将来在使用的时候,使用具体的子类型参与操作

弊端
不能使用子类的特有功能
目的
为了不疲于对多个子类进行编辑 通过多态直接对父类编辑
转型
为了使用子类中的特有方法

####### 向上转型
从子到父

######## 父类引用指向子类对象

####### 向下转型
从父到子

######## 父类引用转为子类对象

######### 强转的升级版

抽象类

在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类
特点
抽象类和抽象方法必须使用 abstract 关键字修饰
抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
参照多态的方式,通过子类对象实例化,这叫抽象类多态
抽象类的子类
要么重写抽象类中的所有抽象方法
要么是抽象类
成员特点
成员变量

####### 可以是变量

####### 也可以是常量

构造方法

####### 有构造方法,但是不能实例化

####### 那么,构造方法的作用是什么呢?用于子类访问父类数据的初始化

成员方法

####### 可以有抽象方法:限定子类必须完成某些动作

####### 也可以有非抽象方法:提高代码复用性

接口

接口用关键字interface修饰
public interface 接口名 {}
类实现接口用implements表示
public class 类名 implements 接口名 {}
接口的子类
要么重写接口中的所有抽象方法
要么是抽象类
成员组成
常量
默认修饰符:public static final
抽象方法
默认修饰符:public abstract
默认方法
public default 返回值类型 方法名(参数列表) { }

####### 默认方法不是抽象方法,所以不强制被重写。但是可以被重写,重写的时候去掉default关键字

####### public可以省略,default不能省略

静态方法
public static 返回值类型 方法名(参数列表) { }

####### 静态方法只能通过接口名调用,不能通过实现类名或者对象名调用

####### public可以省略,static不能省略

私有方法
格式1:private 返回值类型 方法名(参数列表) { }
格式2:private static 返回值类型 方法名(参数列表) { }
默认方法可以调用私有的静态方法和非静态方法
静态方法只能调用私有的静态方法

内部类

就是在一个类中定义一个类
格式
public class 类名{

修饰符 class 类名{
}
}

访问特点
内部类可以直接访问外部类的成员,包括私有
外部类要访问内部类的成员,必须创建对象
形式
在类的成员位置:成员内部类
创建成员内部类对象

####### 外部类名.内部类名 对象名 = 外部类对象.内部类对象;

应用

####### 为了避免被外部修改,所以一般用private修饰,用外部类的方法对内部类对象进行操作

######## get/set升级版

在类的局部位置:局部内部类
局部内部类是在方法中定义的类,所以外界是无法直接使用,需要在方法内部创建对象并使用
该类可以直接访问外部类的成员,也可以访问方法内的局部变量
匿名内部类
前提
存在一个类或者接口,这里的类可以是具体类也可以是抽象类
new 类名或者接口名() {

重写方法;
};

本质
是一个继承了该类或者实现了该接口的子类匿名对象

工具类

构造方法用 private 修饰
为了防止外界创建对象
成员用 public static 修饰
为了让使用类名来访问该成员方法

常用API

定义

使用帮助文档搜索类名
看类在哪个包下
java.lang下的类不需要导包
看类的描述
看构造方法
看成员方法
看返回值 方法名,参数 描述

Scanner

Math

Math 包含执行基本数字运算的方法
public static int abs​(int a)
返回参数的绝对值
public static double ceil​(double a)
返回大于或等于参数的最小double值,等于一个整数
public static double floor​(double a)
返回小于或等于参数的最大double值,等于一个整数
public static int round​(float a)
按照四舍五入返回最接近参数的int
public static int max​(int a,int b)
返回两个int值中的较大值
public static int min​(int a,int b)
返回两个int值中的较小值
public static double pow​(double a,double b)
返回a的b次幂的值
public static double random​()
返回值为double的正值,[0.0,1.0)

System

System 包含几个有用的类字段和方法,它不能被实例化
public static void exit​(int status)
终止当前运行的 Java 虚拟机,非零表示异常终止
public static long currentTimeMillis​()
返回当前时间(以毫秒为单位)

Object

Object 是类层次结构的根,每个类都可以将 Object 作为超类。所有类都直接或者间接的继承自该类
构造方法:public Object()
public String toString()
返回对象的字符串表示形式。建议所有子类重写该方法,自动生成
public boolean equals(Object obj)
比较对象是否相等。默认比较地址,重写可以比较内容,自动生成

Arrays

Arrays 类包含用于操作数组的各种方法
public static String toString​(int[] a)
返回指定数组的内容的字符串表示形式
public static void sort​(int[] a)
按照数字顺序排列指定的数组

基本类型包装

将基本数据类型封装成对象的好处在于可以在对象中定义更多的功能方法操作该数据
常用的操作之一:用于基本数据类型与字符串之间的转换
byte
Byte
short
Short
int
Integer
public static Integer valueOf​(int i)

####### 返回表示指定的 int 值的 Integer 实例

public static Integer valueOf​(String s)

####### 返回一个保存指定值的 Integer 对象 String

public static int parseInt​(String s)

####### 将字符串解析为 int 类型

long
Long
float
Float
double
Double
char
Character
boolean
Boolean

日期类

Date
public Date()
分配一个 Date对象,并初始化,以便它代表它被分配的时间,精确到毫秒
public Date(long date)
分配一个 Date对象,并将其初始化为表示从标准基准时间起指定的毫秒数
public long getTime()
获取的是日期对象从1970年1月1日 00:00:00到现在的毫秒值
public void setTime(long time)
设置时间,给的是毫秒值
SimpleDateFormat
日期格式化和解析
y 年
M 月
d 日
H 时
m 分
s 秒
public SimpleDateFormat​()
构造一个SimpleDateFormat,使用默认模式和日期格式
public SimpleDateFormat​(String pattern)
构造一个SimpleDateFormat使用给定的模式和默认的日期格式
public final String format(Date date)
将日期格式化成日期/时间字符串
public Date parse​(String source)
从给定字符串的开始解析文本以生成日期
Calendar
Calendar 为某一时刻和一组日历字段之间的转换提供了一些方法,并为操作日历字段提供了一些方法
Calendar rightNow = Calendar.getInstance();
Calendar 提供了一个类方法 getInstance 用于获取 Calendar 对象,其日历字段已使用当前日期和时间初始化
public int get​(int field)
返回给定日历字段的值
public abstract void add​(int field, int amount)
根据日历的规则,将指定的时间量添加或减去给定的日历字段
public final void set​(int year,int month,int date)
设置当前日历的年月日

异常

程序出现了不正常的情况

Throwable

Java语言中所有错误和异常的超类

Error

严重问题,不需要处理

Exception

异常类,它表示程序本身可以处理的问题

RuntimeException

在编译期是不检查的,出现问题后,需要我们回来修改代码

####### 所有的 RuntimeException 类及其子类被称为运行时异常

######## 无需显示处理,也可以和编译时异常一样处理

######### 运行时异常可以不处理,出现问题后,需要我们回来修改代

####### 其他的异常都是编译时异常

######## 必须显示处理,否则程序就会发生错误,无法通过编译

######### 编译时异常必须要进行处理,两种处理方案:try…catch …或者 throws,如果采用 throws 这种方案,将来谁调用谁处理

非RuntimeException

l编译期就必须处理的,否则程序不能通过编译,就更不能正常运行了

Throwable 的成员方法
public String getMessage​()
返回此 throwable 的详细消息字符串
public String toString​()
返回此可抛出的简短描述
public void printStackTrace​()
把异常的错误信息输出在控制台

####### printStackTrace打印信息最全 用的最多

JVM的默认处理方案
把异常的名称,异常原因及异常出现的位置等信息输出在了控制台
程序停止执行
异常处理
try {

可能出现异常的代码;
} catch(异常类名 变量名) {
异常的处理代码;
}

程序从 try里面的代码开始执行

出现异常,会自动生成一个异常类对象,该异常对象将被提交给Java运行时系统
当Java运行时系统接收到异常对象时,会到catch中去找匹配的异常类,找到后进行异常的处理
执行完毕之后,程序还可以继续往下执行

try{
    可能出现异常的代码;

}catch(异常类名 变量名){
异常的处理代码;
}finally{
执行所有清除操作;
}

throws 异常类名;
自定义异常
public class 异常类名 extends Exception {

无参构造
带参构造
}

泛型

概述

泛型:是JDK5中引入的特性,它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型
它的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数
一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?
顾名思义,就是将类型由原来的具体的类型参数化,然后在使用/调用时传入具体的类型
这种参数类型可以用在类、方法和接口中,分别被称为泛型类、泛型方法、泛型接口

格式

<类型>:指定一种类型的格式。这里的类型可以看成是形参
<类型1,类型2…>:指定多种类型的格式,多种类型之间用逗号隔开。这里的类型可以看成是形参
将来具体调用时候给定的类型可以看成是实参,并且实参的类型只能是引用数据类型

好处

把运行时期的问题提前到了编译期间
避免了强制类型转换

分类

泛型类
格式:修饰符 class 类名<类型> { }
泛型方法
格式:修饰符 <类型> 返回值类型 方法名(类型 变量名) { }
泛型接口
修饰符 interface 接口名<类型> { }
类型通配符
为了表示各种泛型List的父类,可以使用类型通配符
类型通配符:<?>
List<?>:表示元素类型未知的List,它的元素可以匹配任何的类型
这种带通配符的List仅表示它是各种泛型List的父类,并不能把元素添加到其中
类型通配符上限:<? extends 类型>
List<? extends Number>:它表示的类型是Number或者其子类型
类型通配符下限:<? super 类型>
List<? super Number>:它表示的类型是Number或者其父类型

可变参数

可变参数又称参数个数可变,用作方法的形参出现,那么方法参数个数就是可变的了
格式:修饰符 返回值类型 方法名(数据类型… 变量名) { }
注意事项
这里的变量其实是一个数组
如果一个方法有多个参数,包含可变参数,可变参数要放在最后
可变参数的使用
Arrays工具类中有一个静态方法
public static List asList​(T… a):返回由指定数组支持的固定大小的列表
返回的集合不能做增删操作,可以做修改操作
List接口中有一个静态方法
public static List of​(E… elements):返回包含任意数量元素的不可变列表
返回的集合不能做增删改操作
Set接口中有一个静态方法
public static Set of​(E… elements) :返回一个包含任意数量元素的不可变集合
在给元素的时候,不能给重复的元素
返回的集合不能做增删操作,没有修改的方法

File

它是文件和目录路径名的抽象表示

文件和目录是可以通过File封装成对象的
对于File而言,其封装的并不是一个真正存在的文件,仅仅是一个路径名而已。它可以是存在的,也可以是不存在的。
将来是要通过具体的操作把这个路径的内容转换为具体存在的

方法

构造方法
File​(String pathname) 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例
File​(String parent, String child) 从父路径名字符串和子路径名字符串创建新的 File实例
File​(File parent, String child) 从父抽象路径名和子路径名字符串创建新的 File实例
创建功能
public boolean createNewFile() 当具有该名称的文件不存在时,创建一个由该抽象路径名命名的新空文件
public boolean mkdir() 创建由此抽象路径名命名的目录
public boolean mkdirs() 创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录
删除功能
public boolean delete​() 删除由此抽象路径名表示的文件或目录
判断和获取功能
public boolean isDirectory() 测试此抽象路径名表示的File是否为目录
public boolean isFile() 测试此抽象路径名表示的File是否为文件
public boolean exists() 测试此抽象路径名表示的File是否存在
public String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串
public String getPath() 将此抽象路径名转换为路径名字符串
public String getName() 返回由此抽象路径名表示的文件或目录的名称
public String[] list() 返回此抽象路径名表示的目录中的文件和目录的名称字符串数组
public File[] listFiles() 返回此抽象路径名表示的目录中的文件和目录的File对象数组

路径

绝对路径:完整的路径名,不需要任何其他信息就可以定位它所表示的文件。例如:E:\itcast\java.txt
相对路径:必须使用取自其他路径名的信息进行解释。例如:myFile\java.txt

IO流

本质是数据传输

IO流分类

字节流
InputStream

字节输入流

读数据

int read():一次读取一个字节
int read(byte[] bys):一次读取一个字节数组

FileInputStream
BufferedInputStream
OutputStream

字节输出流

写数据

void write(int by):一次写一个字节
void write(byte[] bys,int index,int len):一次写一个字节数组的一部分

FileOutputStream
BufferedOutputStream
字节流可以复制任意文件数据,有4种方式一般采用字节缓冲流一次读写一个字节数组的方式
字符流
Reader

字符输入流

读数据

int read():一次读取一个字符
int read(char[] chs):一次读取一个字符数组

InputStreamReade

####### FileReader

BufferedReade

####### String readLine():一次读取一个字符串

Writer

字符输出流

写数据

void write(int ch):一次写一个字符
void write(char[] chs,int index,int len):一次写一个字符数组的一部分

OutputStreamWriter

####### FileWriter

BufferedWriter

####### void newLine():写一个换行符

####### void write(String line):一次写一个字符串

字符流只能复制文本数据,有5种方式,一般采用字符缓冲流的特有功能

字节流

OutputStream

字节输出流的所有类的超类

FileOutputStream

文件输出流用于将数据写入File

构造方法

####### FileOutputStream​(String name):创建文件输出流以指定的名称写入文件

步骤

####### 创建字节输出流对象(调用系统功能创建了文件,创建字节输出流对象,让字节输出流对象指向文件)

####### 调用字节输出流对象的写数据方法

####### 释放资源(关闭此文件输出流并释放与此流相关联的任何系统资源)

三个方法

####### void write​(int b) 将指定的字节写入此文件输出流

######## 一次写一个字节数据

####### void write​(byte[] b) 将 b.length字节从指定的字节数组写入此文件输出流

######## 一次写一个字节数组数据

####### void write​(byte[] b, int off, int len) 将 len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流

######## 一次写一个字节数组的部分数据

换行符

####### windows:\r\n

####### linux:\n

####### mac:\r

追加写入

####### public FileOutputStream​(String name,boolean append)

######## 如果第二个参数为true ,则字节将写入文件的末尾而不是开头

BufferOutputStream

字节缓冲输出流

构造方法

####### BufferedOutputStream​(OutputStream out)

######## 为什么构造方法需要的是字节流,而不是具体的文件或者路径呢?

InputStream

字节输入流的所有类的超类

FileInputStream

从文件系统中的文件获取输入字节

构造方法

####### FileInputStream​(String name):通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名

步骤

####### 创建字节输入流对象

####### 调用字节输入流对象的读数据方法

####### 释放资源

一次读一个字节数组的方法

####### public int read​(byte[] b):从输入流读取最多b.length个字节的数据

####### 返回的是读入缓冲区的总字节数,也就是实际的读取字节个数

BufferedInputStream

字节缓冲输入流

构造方法

####### BufferedInputStream​(InputStream in)

######## 字节缓冲流仅仅提供缓冲区,而真正的读写数据还得依靠基本的字节流对象进行操作

字符流

用记事本打开能读懂

概论
由于字节流操作中文不是特别的方便,所以Java就提供字符流
字符流 = 字节流 + 编码表
汉字在存储的时候,无论选择哪种编码存储,第一个字节都是负数
采用何种规则编码,就要采用对应规则解码,否则就会出现乱码
编码
byte[] getBytes​():使用平台的默认字符集将该 String编码为一系列字节,将结果存储到新的字节数组中
byte[] getBytes​(String charsetName):使用指定的字符集将该 String编码为一系列字节,将结果存储到新的字节数组中
解码
String​(byte[] bytes):通过使用平台的默认字符集解码指定的字节数组来构造新的 String
String​(byte[] bytes, String charsetName):通过指定的字符集解码指定的字节数组来构造新的 String
Writer

字符输出流的抽象类

OutputStreamWriter
写数据的5种方式

####### void write​(int c) 写一个字符

####### void write​(char[] cbuf) 写入一个字符数组

####### void write​(char[] cbuf, int off, int len) 写入字符数组的一部分

####### void write​(String str) 写一个字符串

####### void write​(String str, int off, int len) 写一个字符串的一部分

####### flush() 刷新流,还可以继续写数据

####### close() 关闭流,释放资源,但是在关闭之前会先刷新流。一旦关闭,就不能再写数据

FileWriter(String fileName)

####### 用于写入字符文件的便捷类

BufferedWriter

字符缓冲输出流

构造方法

####### BufferedWriter​(Writer out)

特有功能

####### void newLine​():写一行行分隔符,行分隔符字符串由系统属性定义

Reader

字符输入流的抽象类

InputStreamReader
读数据的2种方式

####### int read​() 一次读一个字符数据

####### int read​(char[] cbuf) 一次读一个字符数组数据

FileRead(String fileName)

####### 用于读取字符文件的便捷类

BufferedReader

字符缓冲输入流

构造方法

####### BufferedReader​(Reader in)

特有功能

####### public String readLine​() :读一行文字。 结果包含行的内容的字符串,不包括任何行终止字符,如果流的结尾已经到达,则为null

特殊操作流

标准输入输出流
public static final InputStream in:标准输入流。通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源
public static final PrintStream out:标准输出流。通常该流对应于显示输出或由主机环境或用户指定的另一个输出目标
打印流
字节打印流:PrintStream
PrintStream​(String fileName):使用指定的文件名创建新的打印流
使用继承父类的方法写数据,查看的时候会转码;使用自己的特有方法写数据,查看的数据原样输出
可以改变输出语句的目的地

public static void setOut​(PrintStream out):重新分配“标准”输出流

字符打印流:PrintWriter
构造方法

####### PrintWriter​(String fileName) 使用指定的文件名创建一个新的PrintWriter,而不需要自动执行刷新

####### PrintWriter​(Writer out, boolean autoFlush) 创建一个新的PrintWriter

######## out:字符输出流

######## autoFlush: 一个布尔值,如果为真,则println , printf ,或format方法将刷新输出缓冲区

特点
只负责输出数据,不负责读取数据
永远不会抛出IOException
有自己的特有方法
对象序列化流
概述
将对象保存到磁盘中,或者在网络中传输对象
这种机制就是使用一个字节序列表示一个对象,该字节序列包含:对象的类型、对象的数据和对象中存储的属性等信息
字节序列写到文件之后,相当于文件中持久保存了一个对象的信息
反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列
对象序列化流:ObjectOutputStream
构造方法

####### ObjectOutputStream​(OutputStream out):创建一个写入指定的OutputStream的ObjectOutputStream

序列化对象的方法

####### void writeObject​(Object obj):将指定的对象写入ObjectOutputStream

注意

####### 一个对象要想被序列化,该对象所属的类必须必须实现Serializable 接口

######## Serializable是一个标记接口,实现该接口,不需要重写任何方法

对象反序列化流:ObjectInputStream
构造方法

####### ObjectInputStream​(InputStream in):创建从指定的InputStream读取的ObjectInputStream

反序列化对象的方法

####### Object readObject​():从ObjectInputStream读取一个对象

三个问题
用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类文件,读取数据会不会出问题呢?

####### 会出问题,会抛出InvalidClassException异常

如果出问题了,如何解决呢?

####### 重新序列化

####### 给对象所属的类加一个serialVersionUID

####### private static final long serialVersionUID = 42L;

如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?

####### 给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程

Properties和IO流结合的方法

void load​(InputStream inStream) 从输入字节流读取属性列表(键和元素对)
void load​(Reader reader) 从输入字符流读取属性列表(键和元素对)(推荐)
void store​(OutputStream out, String comments) 将此属性列表(键和元素对)写入此 Properties表中,以适合于使用 load(InputStream)方法的格式写入输出字节流
void store​(Writer writer, String comments) 将此属性列表(键和元素对)写入此 Properties表中,以适合使用 load(Reader)方法的格式写入输出字符流(推荐)

递归

方法定义中调用方法本身的现象

把一个复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解

递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算

两个内容

递归出口:否则会出现内存溢出
递归规则:与原问题相似的规模较小的问题

线程

进程:是正在运行的程序

是系统进行资源分配和调用的独立单位
每一个进程都有它自己的内存空间和系统资源

线程:是进程中的单个顺序控制流,是一条执行路径

单线程:一个进程如果只有一条执行路径,则称为单线程程序
多线程:一个进程如果有多条执行路径,则称为多线程程序

多线程实现方法

方案1

Thread

继承Thread类
定义一个类MyThread继承Thread类
在MyThread类中重写run()方法
创建MyThread类的对象
启动线程
两个小问题

####### 为什么要重写run()方法?

######## 因为run()是用来封装被线程执行的代码

####### run()方法和start()方法的区别?

######## run():封装线程执行的代码,直接调用,相当于普通方法的调用

######## start():启动线程;然后由JVM调用此线程的run()方法

设置和获取线程名称
void setName​(String name):将此线程的名称更改为等于参数 name
String getName​():返回此线程的名称
通过构造方法也可以设置线程名称
如何获取main()方法所在的线程名称?

####### public static Thread currentThread():返回对当前正在执行的线程对象的引用

设置和获取线程优先级的方法
public final intgetPriority():返回此线程的优先级
public final void setPriority(int newPriority):更改此线程的优先级
线程默认优先级是5;线程优先级的范围是:1-10
方案2

Runnable

实现Runnable接口
定义一个类MyRunnable实现Runnable接口
在MyRunnable类中重写run()方法
创建MyRunnable类的对象
创建Thread类的对象,把MyRunnable对象作为构造方法的参数
启动线程
相比继承Thread类,实现Runnable接口的好处
避免了Java单继承的局限性
适合多个相同程序的代码去处理同一个资源的情况,把线程和程序的代码、数据有效分离,较好的体现了面向对象的设计思想

线程调度

Java使用的是抢占式调度模型
优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程
获取的 CPU 时间片相对多一些

线程控制

static void sleep​(long millis) 使当前正在执行的线程停留(暂停执行)指定的毫秒数
void join​() 等待这个线程死亡
void setDaemon​(boolean on) 将此线程标记为守护线程,当运行的线程都是守护线程时,Java虚拟机将退出

生产者消费者模式

包含了两类线程
一类是生产者线程用于生产数据
一类是消费者线程用于消费数据
为了解耦生产者和消费者的关系,通常会采用共享的数据区域
生产者生产数据之后直接放置在共享数据区中,并不需要关心消费者的行为
消费者只需要从共享数据区中去获取数据,并不需要关心生产者的行为
方法
void wait​() 导致当前线程等待,直到另一个线程调用该对象的 notify()方法或 notifyAll()方法
void notify​() 唤醒正在等待对象监视器的单个线程
void notifyAll​() 唤醒正在等待对象监视器的所有线程

数据安全问题

判断多线程程序是否会有数据安全问题的标准

是否是多线程环境
是否有共享数据
是否有多条语句操作共享数据

如何解决多线程安全问题呢

基本思想:让程序没有安全问题的环境

怎么实现呢

把多条语句操作共享数据的代码给锁起来,让任意时刻只能有一个线程执行即可
Java提供了同步代码块的方式来解决

同步代码块

格式:
  synchronized(任意对象) { 
           多条语句操作共享数据的代码 
   }
好处:解决了多线程的数据安全问题
弊端:当线程很多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中会降低程序的运行效率

同步方法

同步方法
格式

修饰符 synchronized 返回值类型 方法名(方法参数) { }

同步方法的锁对象是this
同步静态方法
格式

修饰符 staticsynchronized 返回值类型
方法名(方法参数)
{ }

同步静态方法的锁对象是类名.class

线程安全的类

StringBuffer
线程安全,可变的字符序列
从版本JDK 5开始,被StringBuilder 替代。 通常应该使用StringBuilder类,因为它支持所有相同的操作,但它更快,因为它不执行同步
Vector
从Java 2平台v1.2开始,该类改进了List接口,使其成为Java Collections Framework的成员。 与新的集合实现不同, Vector被同步。 如果不需要线程安全的实现,建议使用ArrayList代替Vector
Hashtable
该类实现了一个哈希表,它将键映射到值。 任何非null对象都可以用作键或者值
从Java 2平台v1.2开始,该类进行了改进,实现了Map接口,使其成为Java Collections Framework的成员。 与新的集合实现不同, Hashtable被同步。 如果不需要线程安全的实现,建议使用HashMap代替Hashtable

Lock锁

Lock实现提供比使用synchronized方法和语句可以获得更广泛的锁定操作
Lock中提供了获得锁和释放锁的方法
void lock():获得锁
void unlock():释放锁
采用Lock的实现类ReentrantLock来实例化
ReentrantLock​():创建一个ReentrantLock的实例

网络编程

计算机网络

是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统

网络编程

在网络通信协议下,实现网络互连的不同计算机上运行的程序间可以进行数据交换
三要素
IP地址
网络中设备的唯一标识

####### IPv4

####### IPv6

####### 常用命令

######## ipconfig:查看本机IP地址

######## ping IP地址:检查网络是否连通

######## 特殊IP地址

######### 127.0.0.1:是回送地址,可以代表本机地址,一般用来测试使用

InetAddress

####### 方便我们对IP地址的获取和操作

####### 此类表示Internet协议(IP)地址

####### 方法

######## static InetAddress getByName​(String host) 确定主机名称的IP地址。主机名称可以是机器名称,也可以是IP地址

######## String getHostName​() 获取此IP地址的主机名

######## String getHostAddress​() 返回文本显示中的IP地址字符串

端口
设备上应用程序的唯一标识
端口号:用两个字节表示的整数,它的取值范围是0~65535
协议
计算机网络中,连接和通信的规则被称为网络通信协议

####### UDP协议
无连接通信协议

######## 发送数据的步骤

######### 创建发送端的Socket对象(DatagramSocket)

########## DatagramSocket​()

######### 创建数据,并把数据打包

########## DatagramPacket​(byte[] buf, int length, InetAddress address, int port)

######### 调用DatagramSocket对象的方法发送数据

########## void send​(DatagramPacket p)

######### 关闭发送端

########## void close()

######## 接收数据的步骤

######### 创建接收端的Socket对象(DatagramSocket)

########## DatagramSocket​(int port)

######### 创建一个数据包,用于接收数据

########## DatagramPacket​(byte[] buf, int length)

######### 调用DatagramSocket对象的方法接收数据

########## void receive​(DatagramPacket p)

######### 解析数据包,并把数据在控制台显示

########## byte[] getData​()

########## int getLength​()

######### 关闭接收端

########## void close()

####### TCP协议
面向连接的通信协议

######## “三次握手”

######## 发送数据的步骤

######### 创建客户端的Socket对象(Socket)

########## Socket​(String host, int port)

######### 获取输出流,写数据

########## OutputStream getOutputStream​()

######### 释放资源

########## void close​()

######## 接收数据的步骤

######### 创建服务器端的Socket对象(ServerSocket)

########## ServerSocket​(int port)

######### 监听客户端连接,返回一个Socket对象

########## Socket accept​()

######### 获取输入流,读数据,并把数据显示在控制台

########## InputStream getInputStream​()

######### 释放资源

########## void close​()

Lambda表达式

强调做什么,而不是以什么形式去做

三要素

形式参数
如果有多个参数,参数之间用逗号隔开;如果没有参数,留空即可
箭头
由英文中画线和大于符号组成,固定写法。代表指向动作
代码块
是我们具体要做的事情,也就是以前我们写的方法体内容

使用前提

有一个接口
接口中有且仅有一个抽象方法

省略规则:

参数类型可以省略。但是有多个参数的情况下,不能只省略一个
如果参数有且仅有一个,那么小括号可以省略
如果代码块的语句只有一条,可以省略大括号和分号,甚至是return

注意事项:

必须有上下文环境,才能推导出Lambda对应的接口
根据局部变量的赋值得知Lambda对应的接口
根据调用方法的参数得知Lambda对应的接口

方法引用

::

:: 该符号为引用运算符,而它所在的表达式被称为方法引用

推导与省略

如果使用Lambda,那么根据“可推导就是可省略”的原则,无需指定参数类型,也无需指定的重载形式,它们都将被自动推导
如果使用方法引用,也是同样可以根据上下文进行推导
方法引用是Lambda的孪生兄弟

常见的引用方式:

引用类方法
引用类的静态方法
格式:类名::静态方法
引用对象的实例方法
引用类中的成员方法
格式:对象::成员方法
引用类的实例方法
引用类类中的成员方法
格式:类名::成员方法
引用构造器
引用构造方法
类名::new

函数式接口

有且仅有一个抽象方法的接口

@FunctionalInterface

放在接口定义的上方:如果接口是函数式接口,编译通过;如果不是,编译失败

函数式接口作为方法的参数

函数式接口作为方法的返回值

Supplier接口

Supplier:包含一个无参的方法
T get​():获得结果
该方法不需要参数,它会按照某种实现逻辑(由Lambda表达式实现)返回一个数据
Supplier接口也被称为生产型接口,如果我们指定了接口的泛型是什么类型,那么接口中的get方法就会生产什么类型的数据供我们使用

Consumer接口

Consumer:包含两个方法
void accept​(T t):对给定的参数执行此操作
default Consumer andThen​(Consumer after):返回一个组合的 Consumer,依次执行此操作,然后执行 after操作
Consumer接口也被称为消费型接口,它消费的数据的数据类型由泛型指定

Predicate接口

Predicate:常用的四个方法
boolean test​(T t):对给定的参数进行判断(判断逻辑由Lambda表达式实现),返回一个布尔值
default Predicate negate​():返回一个逻辑的否定,对应逻辑非
default Predicate and​(Predicate other):返回一个组合判断,对应短路与
default Predicate or​(Predicate other):返回一个组合判断,对应短路或
Predicate接口通常用于判断参数是否满足指定的条件

Function接口

Function<T,R>:常用的两个方法
R apply​(T t):将此函数应用于给定的参数
default Function andThen​(Function after):返回一个组合函数,首先将该函数应用于输入,然后将after函数应用于结果
Function<T,R>接口通常用于对参数进行处理,转换(处理逻辑由Lambda表达式实现),然后返回一个新的值

类加载

JVM将会连续完成这三个步骤

类的加载

就是指将class文件读入内存,并为之创建一个 java.lang.Class 对象
任何类被使用时,系统都会为之建立一个 java.lang.Class 对象

类的连接

验证阶段:用于检验被加载的类是否有正确的内部结构,并和其他类协调一致
准备阶段:负责为类的类变量分配内存,并设置默认初始化值
解析阶段:将类的二进制数据中的符号引用替换为直接引用

类的初始化

在该阶段,主要就是对类变量进行初始化
类的初始化步骤
假如类还未被加载和连接,则程序先加载并连接该类
假如该类的直接父类还未被初始化,则先初始化其直接父类
假如类中有初始化语句,则系统依次执行这些初始化语句
注意:在执行第2个步骤的时候,系统对直接父类的初始化步骤也遵循初始化步骤1-3
类的初始化时机:
创建类的实例
调用类的类方法
访问类或者接口的类变量,或者为该类变量赋值
使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
初始化某个类的子类
直接使用java.exe命令来运行某个主类

类加载器

负责将.class文件加载到内存中,并为之生成对应的 java.lang.Class 对象
JVM的类加载机制
全盘负责:就是当一个类加载器负责加载某个Class时,该Class所依赖的和引用的其他Class也将由该类加载器负责载入,除非显示使用另外一个类加载器来载入
父类委托:就是当一个类加载器负责加载某个Class时,先让父类加载器试图加载该Class,只有在父类加载器无法加载该类时才尝试从自己的类路径中加载该类
缓存机制:保证所有加载过的Class都会被缓存,当程序需要使用某个Class对象时,类加载器先从缓存区中搜索该Class,只有当缓存区中不存在该Class对象时,系统才会读取该类对应的二进制数据,并将其转换成Class对象,存储到缓存区

ClassLoader

负责加载类的对象

Bootstrap class loader:它是虚拟机的内置类加载器,通常表示为null ,并且没有父null
Platform class loader:平台类加载器可以看到所有平台类 ,平台类包括由平台类加载器或其祖先定义的Java SE平台API,其实现类和JDK特定的运行时类
System class loader:它也被称为应用程序类加载器 ,与平台类加载器不同。 系统类加载器通常用于定义应用程序类路径,模块路径和JDK特定工具上的类
两个方法
static ClassLoader getSystemClassLoader​():返回用于委派的系统类加载器
ClassLoader getParent​():返回父类加载器进行委派

反射

在运行时去获取一个类的变量和方法信息。然后通过获取到的信息来创建对象,调用方法的一种机制

由于这种动态性,可以极大的增强程序的灵活性,程序不用在编译期就完成确定,在运行期仍然可以扩展

获取Class类的对象

使用类的class属性来获取该类对应的Class对象。举例:Student.class将会返回Student类对应的Class对象
调用对象的getClass()方法,返回该对象所属类对应的Class对象
该方法是Object类中的方法,所有的Java对象都可以调用该方法
使用Class类中的静态方法forName(String className),该方法需要传入字符串参数,该字符串参数的值是某个类的全路径,也就是完整包名的路径

Class类中用于获取构造方法的方法

Constructor<?>[] getConstructors​():返回所有公共构造方法对象的数组
Constructor<?>[] getDeclaredConstructors​():返回所有构造方法对象的数组
Constructor getConstructor​(Class<?>… parameterTypes):返回单个公共构造方法对象
Constructor getDeclaredConstructor​(Class<?>… parameterTypes):返回单个构造方法对象
Constructor类中用于创建对象的方法
T newInstance​(Object… initargs):根据指定的构造方法创建对象

Class类中用于获取成员变量的方法

Field[] getFields​():返回所有公共成员变量对象的数组
Field[] getDeclaredFields​():返回所有成员变量对象的数组
Field getField​(String name):返回单个公共成员变量对象
Field getDeclaredField​(String name):返回单个成员变量对象
Field类中用于给成员变量赋值的方法
void set​(Object obj, Object value):给obj对象的成员变量赋值为value

Class类中用于获取成员方法的方法

Method[] getMethods​():返回所有公共成员方法对象的数组,包括继承的
Method[] getDeclaredMethods​():返回所有成员方法对象的数组,不包括继承的
Method getMethod​(String name, Class<?>… parameterTypes) :返回单个公共成员方法对象
Method getDeclaredMethod​(String name, Class<?>… parameterTypes):返回单个成员方法对象
Method类中用于调用成员方法的方法
Object invoke​(Object obj, Object… args):调用obj对象的成员方法,参数是args,返回值是Object类型

模块化

基本使用步骤

创建模块(按照以前的讲解方式创建模块,创建包,创建类,定义方法)
为了体现模块的使用,我们创建2个模块。一个是myOne,一个是myTwo
在模块的src目录下新建一个名为module-info.java的描述性文件,该文件专门定义模块名,访问权限,模块依赖等信息
描述性文件中使用模块导出和模块依赖来进行配置并使用
模块中所有未导出的包都是模块私有的,他们是不能在模块之外被访问的
在myOne这个模块下的描述性文件中配置模块导出
模块导出格式:exports 包名;
一个模块要访问其他的模块,必须明确指定依赖哪些模块,未明确指定依赖的模块不能访问
在myTwo这个模块下的描述性文件中配置模块依赖
模块依赖格式:requires 模块名;
注意:写模块名报错,需要按下Alt+Enter提示,然后选择模块依赖
在myTwo这个模块的类中使用依赖模块下的内容

Error如漫漫长夜,你我的答案是不灭的流星

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值