JAVASE基础知识笔记
1、继承
-
子类不可继承父类的构造器,因为子类有自己的构造器;但子类可以继承父类的私有成员(成员变量,方法),只是子类无法直接访问,可以通过setter/getter方法访问父类的private成员变量。
-
当子类继承父类后,发现某些方法不足或不适用,就可以重写该方法,修改为满足自己要求的方法体;子类在重写父类的方法后,如果还需要用到父类该方法的功能,不需要再写一遍,只需要通过super.方法名调用即可。
-
方法重写的注意事项:
a.方法重写的前提是有继承关系(有实现关系) b.子类方法重写父类方法,要求 子类方法权限 >= 父类方法的权限 Java中有四个权限,从大到小分别是: public protected 默认的(defulet,不写) private c.重写方法时,除了权限和方法体之外,其他的必须和父类方法一模一样(但是一般来说我们权限也写出一样)
-
继承后子类构造方法特点:
子类所有构造方法的第一行都会使用super()先调用父类的无参构造器,先初始化父类中的成员变量,再执行自己的初始化操作 。子类的任何一个构造,第一行默认(写和不写都行)都有一句代码: super(),代表调用父类的无参构造!
-
-
super和this
this.成员变量名 访问本类的成员变量 super.成员变量名 访问父类的成员变量 this.成员方法名() 调用本类的成员方法 super.成员方法名() 调用父类的成员方法 super(); //子类的构造方法第一行默认调用父类无参构造 super(参数); //我们可以手动修改,调用父类的有参构造 this(); //可以在本类的某个构造中,调用本类的无参构造 this(参数);//可以在本类的某个构造中,调用本类的有参构造
-
继承的特点
a.Java只支持单继承,不支持多继承(一个类只能有一个亲爹),如果支持多继承,会出现方法调用的不确定性 b.Java中一个类可以有多个子类。(一个类可以有多个孩子) c.Java中类可以多层继承(一个子类只能有一个父类,但是其父类也可以有"爷爷"类)
-
抽象类中是有构造方法的,但是不能创建对象;抽象类可以继承抽象类和非抽象类。有抽象方法的一定是抽象类,但抽象类不一定有抽象方法。
2、修饰符
-
final关键字
-
final修饰类后,类不能被继承;
final修饰方法后,方法不能被重写;
final修饰成员变量后,成员变量必须赋值,创建对象之后不能修改该成员变量的值,赋值可以有两种选择: a.定义时直接赋值 b.先定义,后在构造方法中赋值;
final修饰局部变量后,变量变为常量只能被赋值一次;但如果修饰的是引用类型的变量,不变的只是地址值而地址指向的空间中的内容可以改变。
-
final和abstract不能同时出现在类和方法上。
-
-
static关键字
-
static用来修饰成员方法和成员变量,被修饰的成员,称为类成员,也称为静态成员。
类成员/静态成员 不属于对象,属于整个类(属于该类的所有对象共享),建议直接通过类名访问。 -
静态和非静态之间的相互调用
a.静态成员 随着类的加载 而出现在内存(比对象要早出现) b.非静态成员 随着对象的创建 而出现在内存(比静态成员要晚出现) 结论: 在内存中出现的时机: 静态成员 要早于 非静态成员
-
静态方法内不可以定义静态变量
-
3、接口
-
接口和类一样,也是一种引用类型
但是接口中只能定义方法,不能定义成员变量,构造方法
接口中可以有以下几种方法:
a.抽象方法(最常见)
b.默认方法(default修饰符)
c.静态方法(static修饰符)
d.私有方法(JDK1.9,了解即可) -
一个类可以实现多个接口,一个接口可以继承多个接口。
-
a.接口中无法定义变量,但是可以定义常量,由三个修饰符修饰:public、static、final。
b.接口中,没有构造方法,不能创建对象。
c.接口中,没有静态代码块 -
static修饰成员变量时,那么这个成员储存的位置就不在堆中(对象的指向不是堆)
4、多态
-
前提:
1. 要有继承或者实现关系(子父类) 2. 要有方法的重写(没有重写就没有意义) 3. 要有父类引用指向子类对象`Fu fu = new Zi()`
-
访问特点
- 成员变量:编译看左边,运行看左边
- 成员方法:编译看左边,运行看右边
-
多态的好处与弊端:
好处:参数的统一.
弊端:多态的情况下父类的引用不可以调用子类的特有方法,只有调用子类已经重写的父类方法.
5、内部类
-
种类:局部/成员/静态/匿名内部类
-
内部类可以直接使用外部类中的成员
外部类要使用内部类中的成员需要先创建对象
-
内部类会编译成 外部类名$内部类名 的class文件
-
匿名内部类的本质是一个带具体实现的父类或者父接口的匿名的子类对象。
6、代码块
-
分类:普通代码块、构造代码块、静态代码块、同步代码块
-
每次创建对象都会执行构造代码块,优先于构造方法执行
-
静态代码块随着类的加载而执行(只执行一次), 优先于构造方法(构造代码块)执行,用来加载驱动
静态的成员变量(类变量), 可以比静态代码块先执行, 但是要看它们在类中的顺序 静态代码块和静态成员变量(类变量), 谁在前, 谁先执行.
7、常用API
- 为什么要使用基本类型的包装类?
(1)内存 -> 堆内存 栈内存(new进堆 左进栈) int i = 10;基本数据类型不在堆里,就在栈里,因为把基本数据类型放堆里效率低,更高效.
(2)Java是一门面向对象的编程语言,基本数据类型不具备对象的性质(不能调方法都不是引用数据类型[对象]),为了让基本数据类型具有对象的特征.才出现了包装类,它相当于将基本数据类型包装起来,使它具有了对象的特征,并且也有了属性和方法,丰富了基本数据类型的操作.
8、集合
集合和数组主要区别[面试题]:
a.数组长度是固定的 int[] arr = new int[10];
集合长度是可变的 ArrayList arr = new ArrayList();
b.数组的元素可以基本类型也是引用类型
集合的元素只能是引用类型,如果想存基本类型,需要使用基本类型对应的包装类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-omwNXbtm-1606916531825)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1587093365972.png)]
- 迭代器的注意事项:
a.NoSuchElementException 没有此元素异常
原因: 当迭代器的hashNext方法返回false后,我们继续调用next方法
b.ConcurrentModificationException 并发修改异常
原因: 迭代器规定,不能使用迭代器遍历集合的过程中,对集合的元素进行增删操作!!!
- 数据结构:
a.栈结构: 先进后出
b.队列结构: 先进先出
c.数组结构: 查询快,增删慢
d.链表结构: 查询慢,增删快
e.红黑树结构(了解)
红黑树的特点: 查询速度非常恐怖
树结构,二叉树,二叉查找树,平衡二叉树,....,黑红树
- 可变参数:
a、可变参数的本质就是一个数组
b、一个方法中最多只能有一个可变参数,但是可以同时有多个正常参数,必须保证可变参数写在最后
- List接口的特点:
a.有序的:在Java中元素存入和取出的顺序一致时,称为有序(比如:2 1 3 打印集合2 1 3)
b.有索引
c.元素是可重复
b.ArrayList类底层的数据结构是什么?
底层就是采用数组结构,特点查询快,增删慢!!
特有方法: 无!!
c.LinkedList类底层采用什么数据结构??
底层采用链表结构,特点就是查询慢,增删快!!
特有方法: 8个
public void addFirst(E e);添加元素到第一个
public void addLast(E e);添加元素到最后一个
public E getFirst();获取第一个元素
public E getLast();获取最后一个元素
public E removeFirst(); 删除第一个元素
public E removeLast(); 删除最后一个元素
public void push(E e);//添加元素,添加到第一个,底层就是addFirst
public E pop();//删除元素,删除第一个元素,底层就是removeFirst
LinkedList底层使用双向链表
LinkedList内部有一个类,节点类
private static class Node<E> {
E item; //数据域
Node<E> next; //后指针
Node<E> prev; //前指针
}
LinkedList的add方法,默认调用linkLast方法,把元素添加到末尾,并返回true
LinkedList的get方法,调用node方法,该方法会根据我们要查找的元素索引,决定从头开始找还是从尾开始找
- Set接口的特点:
Set接口也有三个特点:
a.无序(在Java中无序是指存入和打印时的顺序不一定一致,比如存入1 2 3 取出 1 3 2)
b.无索引
c.元素唯一
注意事项:
做题的时候,列出Set接口的两个特点: b和c
在Set接口中有一个实现类是有序的(LinkedHashSet有序的)
a.HashSet底层采用的是哈希表结构
哈希表结构 = 数组结构+链表结构+红黑树结构(JDK1.8中加入的)
特点:无序,无索引,元素唯一
b.LinkedHashSet底层采用的是链表+哈希表(链式哈希表)
特有方法: 无!!!
特点: 有序的,无索引,元素唯一
c.TreeSet类底层采用的是红黑树结构
特有方法: 无!!!
特点: 无序(但是它具有自然顺序)!!,无索引,元素唯一
注意: TreeSet是无序的,但是它是无序中一个比较特殊的存在
(存入132打印123,存入312打印123,存入321打印123,存入123打印123)
我们打印出来的地址值并非真正地址值,而是哈希值的16进制表示,在对象的对象名中保存了真正的地址值但是我们无法得到。
哈希表结构如何保证元素唯一性?
哈希值表结构如何判断两个元素是否重复呢?(哈希表结构判断元素重复的依据是什么呢??)
结论: 先比较两个元素的哈希值,如果哈希值一样,再调用equals进行比较
只有哈希值相等,并且equals为true,此时判断才判断元素是重复的!!!!!!!!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zbVh7UlS-1606916531829)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1587094459560.png)]
注意:可以向哈希表中添加null,默认保存在哈希表中数组的0下标中
-
Map的3个常用子类以及其特点(双列集合,键唯一,值可重复)
a.Map<K,V>集合是双列集合的根接口,具有两个泛型 其中K代表键的类型,V代表值的类,K的类和V的类型可以随意,可一样可不一样 b.Map接口有3个实现类: HashMap: 底层采用哈希表结构,无序的 LinkedHashMap:底层采用链式哈希表,有序的 TreeMap:底层采用红黑树结构, 无序的(会按照键的自然顺序默认升序) 共同的特点: Map集合的所有实现类键都是唯一的,值是可以重复的 如果键是自定义类型,为了保证键的唯一性,我们需要重写hashCode和equals方法
-
通用方法:
增: V put(K 键,V 值); 向Map中添加一个键值对,返回null 删: V remove(K 键);从Map中删除键值对,返回被删除的键值对中的值(如果没有删除成功,返回null) 改: V put(K 键,V 值);向Map集合中添加一个已经存在的键时,此时称为修改,返回被修改前的值 查: V get(K 键);以键找值,返回要查找的键对应的值(如果找不到返回null)
9、异常
-
异常的继承体系
所有异常和错误的根类 Throwable |- Error(错误类) |- Exception(异常类) |- 编译时异常(比如:日期DateFormat解析异常) |- 运行时异常(比如:数组越界异常) int[] arr = {1,2,3}; System.out.println(arr[1000]);//运行时异常
-
常用方法
【重点记住这个即可】 public void printStackTrace();在控制台上以血红色打印异常的详细信息(异常的位置,异常的类型,异常的原因) 【以下两个作为了解即可】 public String getMessage(); 获取发生异常的原因 public String toString(); 异常类重写了Object继承toString
-
异常的分类【重点】
-
编译时异常
编译时异常:包括Exception类以及其子类(RuntimeException除外) 特点: 会在编译时报错,我们需要处理异常!!!
-
运行时异常
运行时异常:包含RuntimeException类以及其子类 特点: 即使有异常,编译时期也不会报错,直到程序运行到有异常的代码才报错!!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p7Tvb2qp-1606916531834)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1587302284070.png)]
-
-
Java中异常相关的五个关键字
throw :作用就是抛出一个异常对象,这是一个"动词" throws :throws关键字作用在方法上的,给该方法做声明,表示该方法内部可能会有异常,并且调用方法的调用者处理该异常 try...catch :trycatch可以令程序在局部有问题的情况下,整体还可以继续运行!! finally :finally无法单独使用,需要有trycatch配合使用,写在这里的代码,无论是否有异常,都会执行到
-
注意事项:
a.我们需要throws和trycatch的是编译时异常,而运行时异常我们即不需要throws也不需要trycatch b.父类某个方法抛出多个异常,那么子类重写该方法后最多也只能抛出相同异常或者这些异常的子集 c.如果父类的某个方法没有抛出异常,那么子类重写该方法后不能抛出异常 d.如果有多个异常,我们该如何处理呢??? 代码1: 可能抛出One异常 代码2: 可能抛出Two异常 代码3: 可能抛出Three异常 i.每个异常,分别trycatch try{ 代码1: 可能抛出One异常 }catch(One o){ o.printStackTrace(); } try{ 代码2: 可能抛出Two异常 }catch(Two t){ t.printStackTrace(); } try{ 代码3: 可能抛出Three异常 }catch(Three t){ t.printStackTrace(); } ii.所有异常,一起try,分开catch try{ 代码1: 可能抛出One异常 代码2: 可能抛出Two异常 代码3: 可能抛出Three异常 }catch(One o){ o.printStackTrace(); }catch(Two t1){ t.printStackTrace(); }catch(Three t2){ t.printStackTrace(); } iii.所有异常一起try一起catch[最常用!!] try{ 代码1: 可能抛出One异常 代码2: 可能抛出Two异常 代码3: 可能抛出Three异常 }catch(Exception o){ o.printStackTrace(); } e.在上面的第二种处理方式中,如果这些异常有子父类关系,那么必须把子类写前面,父类写后面 //假设,One异常 继承了 Two异常 try{ 代码1: 可能抛出One异常 代码2: 可能抛出Two异常 代码3: 可能抛出Three异常 }catch(One o){ o.printStackTrace(); }catch(Two t1){ t.printStackTrace(); }catch(Three t2){ t.printStackTrace(); } f.trycatch可以追加finally代码块,该代码块中的代码一定会被执行,一般写释放资源有关的代码
-
自定义异常:
a.起名要规范: XxxException
b.必须有凭证: 继续Exception或者RuntimeException
c.一般双构造: 无参+String参数
10、多线程
-
进程与线程的区别:
线程一定是属于某个进程的 a.进程拥有独立的内存(包括独立栈和独立堆) b.同一个进程中的多个线程拥有独立的栈和共享的堆(其进程的堆)
-
继承式与实现式创建线程的对比:
实现方式 比 继承方式好!! a.实现方式 弥补了 单继承的不足 b.实现方式更加灵活,继承方式高耦合 c.继承方式不合符低耦合编程思想,而实现方式线程对象和任务对象是由程序员来组合,体现低耦合的思想 综上所述,Java强烈建议使用实现方式!!!
-
高并发:在同一个时间点上有大量的线程,访问同一个资源!!!
线程安全:在高并发的情况下,访问同一资源,出现了"数据污染"的问题!!
-
多线程运行的安全问题:
可见性:当一个共性变量(在主内存中),被修改之后,所有线程的工作内存中副本,并不会立即更新到最新值,这就是所 谓不可见!!! 有序性:编译器,在编译代码,会在不影响代码结果的基础上,对代码进行"重排" 原子性:所谓的原子性是指多句代码执行时,不会被其他线程"打断"(抢走CPU)
-
线程安全问题必须是多个线程对同一个数据发生了修改操作;如果多个线程对同一个数据的操作是读取操作,没有修改操作,则一定不会出现线程安全问题;
-
volatile:当共享变量被volatile修饰了,那么主内存其值的修改,子线程中每次都会从主内存获取最新的值(解决可见性问题),被volatile修饰的变量会禁止代码重排(解决有序性问题)。
-
原子类:AtomicInteger不仅能解决原子性,也能解决可见性和有序性问题!!
AtomicInteger类的工作原理-CAS机制/自旋机制
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g2zDgnji-1606916531839)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1587399644416.png)]
-
线程安全及并发包
-
同步方法也需要锁对象,只是这个锁对象不由我们提供,默认使用当前对象this。
-
同步方法可以写成static,但是还是需要锁对象,默认使用当前类的字节码文件。
-
解决线程安全的三种方式:同步代码块、同步方法、lock锁
-
并发包:这是Java专门为多线程的情况下提供一些类,这些类可以保存多线程情况下是安全(包名:java.util.concurrent)。
-
为什么Hashtable效率低而ConcurrentHashMap效率高?
Hashtable虽然是多线程安全的,但是使用全局锁 ConcurrentHashMap是多线程安全的,但是使用的局部锁(桶锁)+CAS机制,既保证线程安全又保证性能比较高
-
CopyOnWriteArrayList ==> ArrayList CopyOnWriteArraySet ==> HashSet ConcurrentHashMap(Hashtable)==> HashMap
-
产生死锁的条件:
a.至少有两个线程
b.至少有两个锁对象
c.线程必须嵌套获取锁对象 -
线程的六大状态:
-
新建状态、可运行状态、销毁状态、锁阻塞状态、限时等待状态、无限等待状态
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BiOafo58-1606916531841)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1587815841271.png)]
-
Lambda的使用前提:
a.Lambda只能替代函数式接口的实现类或者匿名内部类,函数式接口是指有且只有一个抽象方法的接口 b.Lambda只有以上描述的三个地方可以省略,并且必须满足某种条件才可以省略 省略后Lambda会根据上下文自动推导类型和是否需要返回值
-
Stream相关的方法可以分成两大类: 函数拼接方法: 该方法调用之后,返回的还是流对象,故支持链式编程 stream,limit,skip,map,concat,filter 终结方法: 该方法调用之后,没有返回值或者返回的不是流对象,不支持链式编程 foreach,count 注意: 一个流,只能调用一次函数拼接方法或者终结方法,调用完毕之后该流已经被处理了,不能继续调用其他方法
-
11、IO流
-
相对路径和绝对路径的区别:
绝对路径: 以盘符开头的全路径,称为绝对路径 比如:"C:\\Users\\Administrator\\Desktop\\temp\\aaa\\1.txt" 相对路径: 是以当前项目的根目录为基准的路径 比如: 直接写: "1.txt" 那么表示 "当前项目根目录\\1.txt" 直接写: "aa\\2.txt" 那么表示 "当前项目根目录\\aa\\2.txt"
-
使用File类创建文件的时候,父目录必须存在,否则就会报错。
-
File类的detele()方法既能删除文件也能删除空文件夹(但非空文件夹不能删除) 。
-
递归注意事项:a.不能无限递归,应该有一个出口
b.有出口也不能100%没错,递归到达出口之前次数也不能太多(无限递归会导致内存溢出!!)
-
字节/字符输入流的构造:
a.创建对象fos/fw b.会判断文件是否存在: 如果存在,则会清空文件 如果不存在,则自动创建一个 c.让对象fos/fw和1.txt文件绑定
-
字节/字符输入流的构造:
a.创建对象fis/fr b.判断文件是否存在 如果存在,存在就存在,不清空!!! 如果不存在,则直接抛出异常FileNotFoundException c.让对象fis/fr和文件1.txt绑定
-
字符输出流的flush会刷新缓冲区,写入文件后清空缓冲区,缓冲区满了后会自动flush。
-
properties文件一般作为框架的配置文件,而配置文件一般不会出现中文(注释除外), 所以我们平时练习,或者开发中,尽量不要用中文!!
-
缓冲流是对普通流的封装,使性能更加高效。
-
编码: 把字符 通过字符编码 变成对应的码值的过程
比如: a —> 97
解码: 把码值 通过字符编码 转回对应的字符的过程
比如: 97 —> a -
常见字符集:
"ASCII字符集": 包含美国国家字母,数字,英文标点符号等 其对应的字符编码,称为"ASCII码",所有的ASCII字符都占"一个字节" "GBxxxx字符集": GB2312字符集: 包含了常用汉字,中文标点等,大概有7000多个 GBK字符集: 包含了绝对大多数汉字,繁体字,中文标点等,大概有20000多个 GB18030字符集:包含了基本上所有汉字,繁体字,少数民族文字等,大概有70000多个,其对应的字符编码,称 为"GBK编码",所有汉字在GBK编码中占"两个字节" "Unicode字符集": 全球统一字符集,包含基本上全球220多个国家的文字,标点等... 其对应的字符编码,有"Unicode码点,UTF-8编码,UTF-16编码,UTF-32编码" 我们一般最常用的是"UTF-8编码",在这个编码中一个中文占"3个字节" (了解)ISO-8859-1字符集: 拉丁字符集,西欧国家的字符集,但是我们以后使用服务器Tomcat(7.0)以前,默认使用就是该字符集 当然我们肯定要改成GBK或者UTF-8
-
转换流的理解:
转换输出流: OutputStreamWriter的作用编码,是字符流通向字节流的桥梁
转换输入流: InputStreamReader的作用解码,字节流通向字符流的桥梁 -
序列化流:类必须实现 java.io.Serializable 接口以启用其序列化功能,否则抛出NotSerializableException
该接口java.io.Serializable称为标记接口,没有任何的方法 -
反序列化流的两种异常:
a.InvalidClassException 无效类异常 引起这个异常的原因: 在序列化之后,反序列化之前,修改序列化类中的代码,这样原来的类就无效了!! b.ClassNotFoundException 找不到类异常 引起这个异常的原因: 在序列化之后,反序列化之前,删除序列化类,那么反序列化时就找不到该类了!! 关于无效类异常的一些判断机制: a.JVM通过什么方式来判断类是否有效呢??? 比较流中(文件中)的serialVersionUID 和 本地类的serialVersionUID, 如果不一致就会抛出无效类异常 b.如果序列化之后,就需要修改类的代码,反序列难道就没有办法成功了吗? 有办法,让程序员自己管理这个类的序列化版本号即可,其格式必须是 public static final long serialVersionUID = 1L; c.关键字transient 语法: 用于修饰成员变量 作用: 被transient修饰的成员变量和没有transient修饰的成员变量,没有任何区别!!! 当一个对象需要序列化时,序列化流会忽略被transient修饰的成员变量
-
打印流永远不会抛出IO异常(可能抛出其他异常),可以打印各种数据类型(所见即所得)
-
装饰设计模式
作用:在不修改原类也不使用继承的基础上,对原类的功能进行增强 基本步骤:- 装饰类和被装饰类必须实现相同的接口 - 在装饰类中必须传入被装饰类的引用 - 在装饰类中对需要扩展的方法进行扩展 - 在装饰类中对不需要扩展的方法调用被装饰类中的同名方法
12、网络编程
-
IP协议:规定了每台连接到网络的计算机如何获取IP
TCP协议: 规定了传输数据时的一些规则
UPD协议: 规定了传输数据时的一些规则 -
网络编程三要素:
a.使用的协议(TCP) b.IP地址: 网络上计算机的唯一标识(相当于人的身份证号) c.端口号: 一台计算机上的软件的唯一标识 一台计算机上一共有(0-65535)这么端口,我们一般使用1024以上的(1024以下被知名软件服务厂商占用)
-
TCP协议:面向有链接,安全但性能较低
UDP协议:面向无连接,不安全但性能较高
-
***localhost与127.0.0.1的区别:***
localhost也叫local,解释:本地服务器 //localhostb不经过网卡,它不受防火墙和网卡的相关限制。 127.0.0.1解释:本机地址,是windows的host文件会自动把localhost自动解析为127.0.0.1 //127.0.0.1是通过网卡传输的,受到防火墙和网卡相关限制
-
当客户端需要发送的数据发送完毕时,必须用通知服务器(通过关闭输出流的方式),否则服务器会阻塞在获取输入流的地方。
13、NIO与AIO
-
基础概念
阻塞: 当调用某个功能时,如果该功能没有完成,那么程序无法继续向下执行,这可以成为阻塞 非阻塞: 当调用某个功能时,如果该功能没有完成,程序不会等待该功能完成,可以直接继续向下执行 同步: 当调用某个功能时,可能是阻塞,也可以是非阻塞的,如果是非阻塞的,而且功能有结果返回值,那么后期我们需要自己编写代码,来获取该结果 异步: 当调用某个功能时,一般来说是非阻塞的,如果该功能有结果返回呢,后期我们不需要自己编写代码来获取结果,当该功能结束之后,自动去调用某个方法,传入最后的结果(方法回调) BIO(Blocked IO): 传统的IO流,阻塞IO NIO(New IO): 新的IO,可以是同步阻塞的, 也可以是同步非阻塞(后期需要自己通过编写代码判断数据是否读取完毕) AIO(Asynchonous IO): 异步IO,是异步非阻塞的(后期我们不需要编写代码,自动通过某个回调机制,通知我们)
14、反射与注解
-
类的加载
当我们运行代码时,第一次使用到一个类,此时类加载器将该类的字节码文件加载到方法区中!!!! 当类的字节码文件加载到方法区之后,JVM立刻在堆区中创建一个对象,该对象用来保存字节码文件中的所有信息!!! 该对象我们一般称为字节码对象文件或者Class对象
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dvj8s1Uu-1606916531843)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1588928556888.png)]
-
类的加载时机
创建类的实例 访问类的静态成员 调用类的静态方法 用反射方式强制加载某个类 用到某个类的子类 使用javac运行某个主类(含有main方法的类)
-
类加载器的作用和分类
类加载器:用于将类的字节码文件加载到内存的方法区中 类加载器的分类: 启动类加载器(BootStrap ClassLoader):用于加载Java类中大部分的常见类(比如String,Date,...) 扩展类加载器(Extension ClassLoader):用于加载Java类库中ext扩展包下的类 应用程序类加载器(Application ClassLoader): 用于加载我们自己定义的类
-
双亲委派机制
1.某个"类加载器"收到类加载的请求,它首先不会尝试自己去加载这个类,而是把请求交给父级类加载器。 2.因此,所有的类加载的请求最终都会传送到顶层的"启动类加载器"中。 3.如果"父级类加载器"无法加载这个类,然后子级类加载器再去加载。 双亲委派机制有什么作用?? 保存不同的类由对应的类加载器加载,并且一个只会被加载一次
-
私有的成员方法不能直接调用,必须先设置暴力权限为true,再去调用它!
-
注解的三个作用
a.生成帮助文档,@author和@version b.编译检查,@Override c.给我们以后的框架使用,用来作为配置文件(框架+注解)
-
常用注解
1. @author:用来标识作者名,eclipse开发工具默认的是系统用户名。 2. @version:用于标识对象的版本号,适用范围:文件、类、方法。 3. @Override :用于表示方法,表示该方法是重写的 4. @Test: Junit的注解,表示当前方法是一个Junit的测试方法 5. @FunctionalInterface: 函数式接口注解
-
自定义注解
关键字:@interface //注解里面只能写属性 a.只能是8种基本类型(byte,short,int,long,float,double,boolean,char) b.或者4种引用(String,枚举类型,其他注解类型,Class类型) c.或者以上12种类型的一维数组(就是我们基础班学过的只有一个[]的数组)
-
a.使用注解时,必须是@注解名(属性名=属性值),注解中所有的属性必须有值,有默认的属性可以赋值可以不赋值,没有默认值的属性必须赋值 b.自定义的注解默认可以使用各种成分上(包括类上,成员变量上,成员方法上,局部变量上,方法参数上,构造方法上等..)
-
自定义中的特殊属性名value
a.如果一个注解中,只有一个属性,并且名字叫value,使用注解时,给value赋值时,只需要写属性值,属性名可以省略 b.如果一个注解中,有多个属性,但是除了value之外其他属性都有默认值,使用注解时,只给value赋值,只需要写属性值,属性名可以省略
15、XML
-
所有的标准的XML文件,第一行第一列开始必须写文档声明。
-
XML的作用
保存数据(保存框架的配置数据)
传输数据(被json替代) -
XML的组成元素
标签/元素/节点 <开始>内容</结束> 属性 属性名="属性值" 内容 可能普通文本,也可能时嵌套的标签
-
解析XML文档DOM方式原理:将整个XML一起读取到内存,解析后返回一个Document对象
是8种基本类型(byte,short,int,long,float,double,boolean,char)
b.或者4种引用(String,枚举类型,其他注解类型,Class类型)
c.或者以上12种类型的一维数组(就是我们基础班学过的只有一个[]的数组)
9. ```java
a.使用注解时,必须是@注解名(属性名=属性值),注解中所有的属性必须有值,有默认的属性可以赋值可以不赋值,没有默认值的属性必须赋值
b.自定义的注解默认可以使用各种成分上(包括类上,成员变量上,成员方法上,局部变量上,方法参数上,构造方法上等..)
-
自定义中的特殊属性名value
a.如果一个注解中,只有一个属性,并且名字叫value,使用注解时,给value赋值时,只需要写属性值,属性名可以省略 b.如果一个注解中,有多个属性,但是除了value之外其他属性都有默认值,使用注解时,只给value赋值,只需要写属性值,属性名可以省略
15、XML
-
所有的标准的XML文件,第一行第一列开始必须写文档声明。
-
XML的作用
保存数据(保存框架的配置数据)
传输数据(被json替代) -
XML的组成元素
标签/元素/节点 <开始>内容</结束> 属性 属性名="属性值" 内容 可能普通文本,也可能时嵌套的标签
-
解析XML文档DOM方式原理:将整个XML一起读取到内存,解析后返回一个Document对象