知识点:
一、关于 “==” 与“equals"之间比较
==
a、基本类型来说,只要两个变量的值相等,即为true,
b、引用类型来说,是否指向同一个对象,如果是的话 为true.
c、等号两边的数据类型必须兼容,否则编译报错。
equals
a、所有类都继承了Object。所有类都有equals方法。
b、只能比较引用类型,起作用与”==“相同,比较是否指向同一个对象。
c、当使用equals方法对 File,String,Date以及包装类来说 ,是比较类型及内容,而不考虑是否指向同一个对象,原因是这些类重写了 Object类的equals方法。
二、单例设计模式
概念:
在虚拟机中只产生一个对象实例。
做法:
a、构造器私有化,private。私有化构造器的话,类就不能在外部通过new进行实例化。
b、提供对外的静态方法返回当前类的对象的实例,保证对象的唯一性。懒汉 饿汉之分。
饿汉式:
public class Single {
private Single(){}
private static Single single = new Single();
public static Single getSingle(){
return single;
}
}
懒汉式:
public class Single {
//构造器私有化
private Single(){}
//初始化对象为null
private static Single single = null;
//通过方法返回单例模式
public static Single getSingle(){
if(single == null ){
single = new Single();
}
return single;
}
}
线程安全的懒汉式:
public class Single {
//构造器私有化
private Single(){}
//初始化对象为null
private static Single single = null;
//通过方法返回单例模式
public static Single getSingle(){
//需要加双判断
if(single == null ){
synchronized (Single.class){
if(single == null ){
single = new Single();
}
}
}
return single;
}
//构造器私有化
private Single(){}
//初始化对象为null
private static Single single = null;
//通过方法返回单例模式
public static Single getSingle(){
//需要加双判断
if(single == null ){
synchronized (Single.class){
if(single == null ){
single = new Single();
}
}
}
return single;
}
}
缺点:
有反序列化漏洞,当通过网络编程传输的时候ObjectInputStream 在反序列的时候没有对生成的对象的类型做限制,会有readObject()方法反序列化会生成不一样的对象。参考笔记JAVA高效编程中第三条.
推荐通过枚举实现单例模式:
枚举单例模式:
优点:
a、自由序列化
b、保证只有一个实例(即使使用反射机制也无法多次实例化一个枚举量)
c、线程安全 private final
public enum SomeThing {
INSTANCE;
private Resource instance;
SomeThing(){
instance = new Resource();
}
public Resource getInstance(){
return instance;
}
}
INSTANCE;
private Resource instance;
SomeThing(){
instance = new Resource();
}
public Resource getInstance(){
return instance;
}
}
三、关于类成员加载顺序问题
声明成员变量的默认值> 显示的初始化,多个初始化按顺序执行, 构造器在对成员进行赋值操作。
a、static {} > (super类的 {} > 构造器 ) >子类的{} >构造器
b、子类继承父类都是父类先加载,然后在子类
四、final关键字
final关键字可以修饰 类,属性 和方法.
a、修饰类: final标记的类不能被继承。
b、修饰方法:final修饰的方式不能被子类重写。
c、修饰属性:final修饰的属性,成为常量,只能赋值一次。必须在构造器或者代码块中显试的赋值。
五、抽象类 【模板模式】
a、abstract关键字修饰的类或者方法叫做抽象类,或者抽象方法
b、含有抽象方法的类必须是抽象类。
c、抽象类不能被实例化,继承的抽象类如果没有实现抽象方法的话也必须是抽象类。
d、abstract 不能修饰属性,私有方法,构造器,静态方法 final方法。
六、接口
a、抽象方法跟常量的定义的集合。
b、是一种特殊的抽象类。
c、接口不允许有方法的实现,不允许有变量。
d、一个类可以实现多个接口,但是只能继承一个类。
e、接口中所有的成员变量都默认由public static final修饰的,所有方法都默认是public abstract修饰的、
七、java异常
结构图:

八、集合
数组 | 集合 | |
长度 | 固定 | 可变 |
存储元素 | 基本类型/引用类型 | 引用类型 |
元素类型的一致性 | 必须一致 | 可以不一致 |
之间的继承关系: 注意 Collection 跟Map是平级,不是谁继承谁的问题。
Collection <- list set <-arraylist,linkedList,hashset,treeset,<- linkedhashset
Map <- hashmap <-TreeMap <- LinkedHashMap
a、关于hashSet保证唯一性依赖的两个方法【hashCode(),equals()】判断顺序:
顺序:
判断hashCode() 值是否相同 :
相同:
判断equals(),是否为true
true: 不添加到集合
false: 添加到集合
不相同:
就添加到集合
b、TreeSet,TreeMap 结构存储引用类型必须实现Comparable接口,这个是有顺序的。通过该接口返回大于0 小于0 等于0来判断顺序。
c、HashMap 线程不安全,效率高。HashTable线程安全,效率低。 底层是哈希表。
d、TreeMap线程不安全,效率高,有序。底层是二叉树。
e、Map遍历:
键找值: 把所有的键集中起来 Set<K> keySet() 遍历键集合,通过增强For循环,或者迭代期 获取每一个键,通过键找值 get(key).
键值对: 获取键值对集合Set<>entrySet() ,通过增强For,迭代器获取到键值对, getKey(),getValue();
九、泛型
泛型方法:
a、所有泛型方法 需要有个类型参数声明部分,<E> 需要在方法返回值前。
b、泛型方法,只能是引用类型,不能是基础类型。
泛型类:
a、泛型类只需要在类名后添加<E>
十、枚举类
a、枚举类属性使用private final 修饰属性 枚举类单个成员作为一种单例模式的实现方式。
b、枚举类的构造方法只能使用private,私有的,枚举类默认都是继承java.lang.Enum类。
c、枚举类必须在第一行声明枚举类对象。
d、实例化枚举类必须显示列出,系统会自动添加public static final。
十一、注解Annotation
jdk提供了专门在注解上的注解类型
a、Retention:指定注解可以保留多长时间
b、Target:指定注解修可以饰哪些个程序元素
c、Documented:注定被该注解修饰的类提供成javadoc文档,前提是 Retention必须设置值成RUNTIME
d、Inherited: 指定具有继承性,如果父类启用了带该注解的注解之后 子类将继承。
十二、多线程问题
线程生命周期的几种状态
a、新建状态 使用new关键字或者Thread类或其子类简历一个线程对象后,线程处理的状态。
b、就绪状态 线程对象调用start()方法后,线程处于就绪状态。
c、运行状态 就绪状态的线程获取CPU资源,执行run()方法。
d、阻塞状态 线程调用了sleep,suspend,wait 挂起方法。
e、死亡状态 任务完成或者其他终止条件发生,切换到终止状态。
创建线程的方法:
a、实现Runable接口
b、继承Thread类本身
c、通过Callable和Future创建线程
十三、IO流问题
流的分类:
字节流 inputstream outputstream || 字符流 reader writer
十四、反射机制
基本概念
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个 方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。
class
a、一个描述类的类,封装了描述方法的Method,描述字段的Frield,构造器等属性。
b、对象反射可以得到的信息:成员名,方法 和构造器,实现的接口。
c、每个类jre都为其保留一个不变的class类型的对象,且这个对象只能由系统建立。
d、一个类在JVM中只会有一个Class实例。
反射机制获取类的方法:
a、类名.class
b、对象.getClass()
c、Class.forName(全类名)
通过newInstrance创建对象,掉用的类必须有无参的构造器。
十五、类加载器
类的加载过程
JVM将类的加载过程分为 三个步骤
a、装载 Load
b、链接Link (验证,准备,解析)
c、初始化
进一步解释:
1) 装载:查找并加载类的二进制数据;
2)链接:
验证:确保被加载类的正确性;
准备:为类的静态变量分配内存,并将其初始化为默认值;
解析:把类中的符号引用转换为直接引用;
3)初始化:为类的静态变量赋予正确的初始值;

java虚拟机提供了三种类加载器
a、引导类加载器bootstrap
主要是加载JVM自身需要的类,使用C++语言实现。是虚拟机自身一部分 /lib下的核心类库
b、扩展类加载器extension sun公司实现的
sun.misc.Launcher$ExtClassLoader
类 使用java语言实现 /lib/ext目录下 c、系统类加载器system Sun公司实现的
sun.misc.Launcher$AppClassLoader
加载指定classpath路径下的类库 一般情况下该类加载 时程序中默认的类加载器,通过getSystemClassLoader方法可以获取到该类加载器。 三大类加载器的关系:
a、启动类加载器,由c++实现,没有父类
b、扩展类加载器 ExtClassLoader,由java语言实现,父类加载器null
c、系统类加载器 AppClassLoader,由java语言实现,父类加载器器为ExtClassLoader
d、自定义加载器 父类appClassLoader
双亲委派模式:

一个类加载器收到类加载的请求,他不会自己先去加载而是将加载的请求委托给父类加载器执行,如果父类还有父类就仅需进一步向 上委托,依次递归,最终达到顶层启动类加载器。如果父类加载成功就返回,无法加载子类才开始加载。
优势:
a、通过层次加载避免类的重复加载。
b、安全因素,java核心api中定义的类型不会被随意替换掉,