目录
第一章:java语言概述和开发环境:
JVM:Java虚拟机,负责执行指令,管理数据,内存和寄存器。
JDK:java开发安装所需要的。
JRE:包含JVM。
垃圾回收机制:JRE会提供一个后台线程来进行检测和控制,一般是在CPU空闲或内存不足时进行垃圾回收。而程序员不需要
手动回收,垃圾回收机制回收的是堆中对象所占用的内存,而不是物理资源。
优点:
1:提高效率,减少编程的负担
2:保护程序的完整性。
特点:
1:只回收堆内存中没有被引用的对象所占用的内存,不回收物理资源。(如数据库连接,磁盘I/O等)
2:为了更快的引用垃圾回收机制,可以把该对象的引用变量设置为Null。通过这个方式提示垃圾回收机制回收垃圾。
3:(强制垃圾回收)
可以通过调用:System的静态方法:GC;Runtime的实例方法:GC来建议系统进行垃圾回收。(只是建议,还是不能精确控制)
4:垃圾回收机制回收对象时,都会先调用它的finalize()方法,在没有明确指定清理资源时,java就通过这个方法来清理内存。
finalize()方法:
1:不能主动调用它,要交给垃圾回收机制
2:何时被调用有不确定性,也有可能不会被执行
3:当JVM执行科恢复对象的finalize方法是,可能使该对象或系统中其他对象重新变成可达状态。
(可达状态:一个对象被创建后,有一个以上的引用变量引用它,就代表这个对象在程序中是可达状态)
内存泄漏:
对象还没有被释放就放弃了对对象的引用
第二章:理解面对对象:
原理:
除了8个基本类型值以外,一切都是对象。可以把所有事物都看成对象,对象有它的状态和行为,java通过定义成员变量来描述对象的状态,通过定义方法来描述对象的行为。
唯一性:
对象具有唯一性,每个对象都有唯一的标识来引用它,一旦对象没有标识被引用,就会被垃圾回收机制回收。
java语言不允许直接访问对象,都是通过引用来操作对象。
类与对象:
类的具体化是对象,对象的抽象化是类,类里面包括了每个对象的行为特征,它规定了对象锁共同具有的数据和行为特征。
通过New关键字来创建指定类的对象。
第三章:数据类型和运算符:
标识符:
1:字母,数字,下划线和美元符组成,数字不能打头
2:不能试java关键字和保留字,但是可以包含。
3:不能包含空格。
关键字:
所有关键字都是小写的,TRUE,FALSE,NULL不是java关键字。
8大基本类型:
自动类型转换顺序:byte(-128~127)(1字节)--char(2)--short(2)--int(4)--float(短精度)(4)--double(双精度)(8)--long(8)
boolean:布尔类型
运算符:
位运算符:
与:同1为1
&&:只要成立就执行,第一个是false,就不执行。
&:左侧全部运算完才执行,第一个是false,继续执行第二个。
或:有1为1
||:是true就直接执行
|:俩个条件都要判断完才执行。
比较运算符:
==和equals方法:
==: 基本类型:比较值 引用类型:比较地址值,看是否指向同一个对象。
equals:基本类型:比较值 引用类型:比较指向对象的内容。
重写equals:euqals方法是Object的方法,所有引用变量都可以通过这个方法来调用它,判断是否与其他引用对象相同。判断对象相等的方法和==相同,都是引用变量指向同一个对象就返回true,所有equals方法就没有太大意义,这时候就需要通过重写它,来变成程序员自定义的比较方法。
String中的equals方法:底层用==实现,只要俩个字符串所包含的字符序列相同,就返回True。
第四章:流程控制和数组:
选择:Switch中的类型(String,byte,char,short,int,枚举类型)
原因:
1:(
switch后面的括号里面只能放int类型的值,byte,short,char类型,它们会 自动 转换为int类型(精精度小的向大的转化),
对于精度比int大的类型,比如long、float,doulble,不会自动转换为int。如果想使用,就必须强转为int,如(int)float;
jdk1.7并没有新的指令来处理switch string,而是通过调用switch中string.hashCode,将string转换为int从而进行判断。
)
2:不可判断的基本类型:long,float,double,boolean以及他们的包装类
3:case后面必须跟break,不然会一直执行下去,直到default出现
4:default最多只有一个
5:case后面能接的数据类型:byte,char,int,short四种整型类型,枚举类型和String类型(java7以上才允许)
数组对象:存放在堆中。
栈:局部变量 存取速度被堆快,栈里面数据可以共享,线程间不可共享 ,自然销毁
堆:对象 堆里面数据不能共享,线程间可以共享,没有任何引用变量则被销毁。
第五章:面对对象:
修饰符:public,final,abstract,protected,private,static
类:(至少包含一个构造器)
构造器:类创建对象的根本途径(没有构造器,无法创建对象),但不是完全负责创建java对象
无需。定义返回值类型:
构造器的返回值类型是当前类,无需定义当前返回值类型。
(不需要用return来返回当前类的对象,因为构造器的返回值类型是隐式的
用Void声明式定义返回值类型,java会把它当做是方法来执行,就不再是构造器了
)
作用:
访问对象的实例变量
调用对象的方法
static修饰符:
static修饰的方法和成员变量也叫类变量,类方法。
static修饰的成员不能访问static修饰的方法和成员。
(静态变量只能访问静态方法和静态变量,不能访问非静态方法)
原因:static修饰的方法不能用this引用,所以static修饰的方法不能访问static修饰的普通成员
This关键字:指向调用该方法的对象。
变量:
静态变量:static修饰的成员变量。可以通过类名来直接访问。
成员变量:静态变量的实例化,只能通过New出来的对象才能引用。
包装类:包装类可以封装对象的一些属性,然后通过包装类可以查询这些属性,比如最大值,最小值等。
自动装箱/拆箱:int的包装类是Integer,int类型的数据可以直接和Integer类型的数据进行运算,这就是自动拆箱和装箱。
Integer(范围:-128~127)
基本类型转换成字符串类型:
1:ToString方法:是Object类的方法,所有的java对象都有ToString方法。所有的对象都可以和字符串运算,java字符串和对象进行运算时,会默认调用ToString方法的返回值和字符串来进行运算。(所有字符串在前的运算结果都是字符串)
注意:
对象不能为空,为空的会报空指针异常
参数类型为int的就没有这个方法
2:强制转换:把不是String类型的转换成String类型,只能强转原本字符串的东西。(原本不是字符串的话,会报错)
3:String.valueOf():
静态方法,直接通过String就可以调用。可以转换成其他类型。
类成员:Static修饰的成员就是类成员。 单例类:Singleton:只创建一个实例。
Final修饰符:
修饰变量:(一旦获得初始值就不可改变)不可改变。
修饰局部变量:不能对final修饰的形参重新复赋值。
修饰方法:不可重写,可重载。
基本类型:修饰后不能对基本类型变量重新赋值。
修饰类:不可继承。
(不可变类:8个基本类型包装类,String类)
引用类型:修饰后对引用的地址不变,就一直引用一个对象,但是可以通过更改对象来改变引用。
抽象类:用abstract修饰的类,不能被实例化,可以包含成员变量,方法(抽象和非抽象),构造器,初始化块。
abstract:可以修饰成员变量,不可以修饰局部变量。
static与abstract不能同时修饰同一个方法,但可以同时修饰内部类。
接口:包含静态常量,方法(抽象),,,不包含:构造器,初始化块,非抽象方法。
区别:
相同点:
1:都不拿被实例化
2:都可以包含抽象方法,实现接口或继承抽象类的子类都必须实现这些抽象方法。
不同点:
1:一个类可以继承一个抽象类,但可以实现多个接口
2:抽象类中可以有非抽象方法,构造器,初始化块,接口中没有
3:抽象类中可以定义静态常量和成员变量,接口中只能定义静态常量。
内部类:(有问题)
内部类与外部类的区别:
1:多了三个修饰符,private,protect,static,外部类不能使用。
2:非静态内部类不能拥有静态成员。
非静态内部类:
1:非静态内部类可以访问外部类的private成员,但是外部的private成员不能访问非静态内部类。
2:静态成员不能访问非静态成员,外部类的静态方法,静态代码块不能访问非静态内部类,包括不能使用非静态内部类定义变量,创建实例等。不允许在外部类的静态成员直接使用非静态内部类。
3:不能在非静态内部类中定义静态成员,不能有静态方法,静态成员变量,静态初始化块。(可以包含普通初始化块,与外部类初始化块作用相同)
静态内部类:
Static不能修饰外部类,但是可以修饰内部类。
1:静态内部类可以包含静态成员,也可以包含非静态成员。
2:静态内部类不能访问外部类的实例方法,只能访问外部类的类成员。
3:静态内部类的实例访问不能访问外部类的实例方法。
(接口中可以定义内部接口,接口内部类只能是静态内部类)
成员变量:
实例变量:不以Static修饰的变量
类变量:以Static修饰的变量
局部变量:
形参
方法变量(方法内定义)
代码块局部变量(代码块内定义)
方法里,局部变量和成员变量同名,局部变量会覆盖成员变量
隐藏和封装:
封装:将对象的状态信息封装在对象内部,不允许外部程序直接访问对象内部信息。
Private:(当前类)
default:(当前包)
protect:(子类访问)
public:(公共)
第八章:集合框架:
Collection:
1:List:有序,可重复
2:Set:无需,不重复
3:Queue:队列
Map:映射关系
Collection:
add:添加元素
clear:清除元素,长度为0
remove:删除元素
isEmpty:判断是否为空
iterator:遍历集合
Set集合:
HashSet:
线程非安全,不同步。(通过HashCode来确定元素位置)
一个对象如果放入HashSet中,必须先通过重写equals方法和HashCode方法,因为如果通过equals方法判断相等时,HashCod方法也必须判断为相同,不然就会出现你存放一个对象,结果存入了俩个对象的情况。
LinkHashSet:利用HashCode来确定元素位置,并且通过链表维护元素的次序。
TreeSet:采用红黑树来存储集合元素。(线程非安全)
自然排序:Comparable中的Compareto方法来排序
HashSet--TreeSet:
添加,查询比TreeSet方便
List集合:有序,可重复
add:插入
remove:删除
ArrayList:线程不安全,扩容默认1/2
Verctor:线程安全,扩容默认一倍
LinkedList:双链表
Queue:队列
Map集合:
clear:删除键值对
remove:删除
HashMap:线程非安全,可以包含Null
HashTable:线程安全,不可以包含Null
HashMap线程不安全的解决办法:
1:使用HashTable
2:使用Collections类中的synchronizedMap方法
3:使用分段锁保证安全
HashMap的工作原理:
HashMap通过put()和get()方法储存和获取对象。当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算hashcode,然后来储存值对象。当获取对象时,通过键对象的equals()方法找到正确的键值对,然后返回值对象。
HashMap使用链表来解决碰撞问题,当发生碰撞了,对象将会储存在链表的下一个节点中。 HashMap在每个链表节点中储存键值对对象。
第十章:异常处理:
异常处理机制:
1:Try…catch捕获异常:
原理:
执行Try块的代码时出现异常,系统就会自动生成一个异常对象,该异常对象提交给java运行环境,叫做抛异常。
java运行环境收到异常对象时,会寻找处理该异常的Catch块,找到合适的,则把该异常交给该catch块处理,叫做捕获异常。
(如果java找不到Catch块,java程序就会退出)
2:异常类的继承:
Try块被执行了一次,后面的Catch块就就只有一个会被执行。
(如果想要多个Catch块被执行,可以通过Continue开始循环,是try再次执行,这样就会使多个Catch块被执行)
3:一个Catch块可以捕获多个异常:
异常变量:捕获多种类型的异常时,异常变量有final修饰的,所以不能对异常变量重新赋值。
4:Finally回收资源:
回收物理资源
(不管Try块的代码是否出现异常,也不管哪个Catch块被执行,甚至在try或者Catch块执行了return语句,Finally总会被执行)
(Try块是必须的,catch块和Finally块至少出现一个)
5:Throws:声明抛出异常:
抛出异常,交给JVM出来,JVM会打印异常时的跟踪栈信息,并终止程序。(这就是程序遇到异常后自动结束的原因)
抛异常原则:
1:子类方法声明的异常类型要是父类的异常类型的子类或相同。
2:子类抛出的异常要比父类的异常多。
rerun问题:
执行Try块,catch块时遇到return语句或者Throw方法立即结束。
但是,它会先寻找Finally块,如果Finally不存在,程序会终止
如果存在,会先执行Finally块然后再回来执行Try块,Catch中的Return或Throw。
但是如果Finally中有return或Throw,finally块就已经终止,不会再跳回去。
异常链模式:
把捕获一个异常然后接着抛出另一个异常,并且把原始异常信息保存下来是一种典型的链式出来。
跟踪栈信息方法:(PrintstackTrace())
(Closeable,AutoClostable---未知)
第十六章:多线程:
一:继承Thread类:
启动:
1:重写run方法,run方法的方法体表示线程要执行的操作
2:创建Thread类的实例
3:通过调用线程对象的start方法来启动线程
currentThread:Thread类的静态方法,返回当前正在执行的线程对象
getName:Thread类的实例方法,返回当前线程的名称。
(用继承Thread类的方法来创建线程类时,多个线程之间无法共享线程类的实例)
二:实现Runnable接口:
1:重新Runnable接口的run方法
2:创建Runnable接口实现类的对象
3:调用线程对象的statrt方法
三:callable:(未知)
创建线程类的3种方式
多线程的生命周期:(启动线程用start方法,而不是run方法)
新建和就绪状态:(调用完Start方法就进入就绪状态)
运行和阻塞状态:
阻塞状态:
1:调用Sleep方法,主动放弃所占用的处理器资源。
2:调用一个阻塞式I/O方法,在方法返回前,线程处于阻塞状态。
3:线程在等待一个通知
4:程序调用线程时的suspend方法,将线程挂起(但是容易造成死锁)
解除阻塞状态:
1:sleep方法过了指定时间
2:线程调用的I/O方法已返回
3:线程接收到通知
4:对挂起状态的线程调用resume恢复方法。
线程死亡:
run或call方法执行完成,线程结束
线程抛出一个为捕获的异常
直接调用该线程的Stop方法结束线程(容易死锁,不推荐)
(不用对一个死亡的线程使用start方法,使它重新启动)
IsAlive:
就绪,运行,阻塞:true
新建,死亡:flase
Join:让一个线程等待另一个线程完成的方法。
守护线程:Gc处理机制:所以前台线程死亡,后台线程自动死亡
Thread的静态类:
线程睡眠:sleep:进入阻塞状态,睡眠时间内,不会获得执行的机会,可以用来暂停线程
线程让步:YieId:进入就绪状态,让政治执行的线程暂停,让它不会阻塞线程。
(调用YieId方法暂停后,只有优先级与当前线程相同或者更高的处于就绪状态的线程会获得执行的机会)
join和YieId的区别:
1:sleep暂停当前线程后,后给其他线程执行机会,不理会线程优先级
YieId只会让优先级相同或更高的获得执行机会
2:sleep会将线程转入阻塞状态,经过阻塞时间后进入就绪状态。
Yie会强制当前线程进入就绪状态,因此完全又可以让其他线程直接调用
3:sleep要么捕获异常,要么声明异常
YieId则没有声明就抛出任何异常
4:sleep比YieId有更好的可移植性。
线程同步:(银行代取,火车售票)
同步代码块:synchronized
同步方法:synchronized修饰的实例方法(非静态方法)
该类的对象可以被多个线程安全的访问
每个线程调用该对象的任意方法之后都将得到正确结果
每个线程调用该对象的任意方法之后,该对象状态依然保持合理状态
同步锁(LOCK)
死锁:俩个线程相互等待对方同时释放同步监视器,就会发生死锁。
sleep:(不释放锁)
wait:(释放锁)当前线程等待,知道其他线程调用notify,notifyAll来唤醒
notify:获取单个线程
notifyAll:获取多个线程
(Condition:控制线程通信
BlockingQueue:阻塞队列控制线程通信
)