八种基本数据类型
- byte
- short
- int
- long
- boolean
- char
- float
- double
JAVA数组
-
定义数组
- 元素类型[] 数组名 = new 元素类型[元素个数和数组长度];
- 元素类型[] 数组名 = new 元素类型[]{元素1, 元素2, 元素3, 元素4};
JAVA内存的划分
- 寄存器
- 本地方法区
- 方法区
-
栈内存
- 存储局部变量, 变量所属作用域一旦结束, 变量自动释放
- 方法进栈: 局部变量属于方法, 所以方法要先进栈
-
堆内存
- 存储对象, 凡是new建立的都在堆中
- 堆内存中的对象都有一个默认值, int:0, double:0.0, float:0.0f, boolean:false, char:'u0000', 引用类型: null
- 每一个实体都有首地址值
局部代码块
- 限定局部变量的生命周期, 释放内存空间
面向对象
成员变量和局部变量区别
- 成员变量定义在类中, 整个类中都可以访问.
- 局部变量定义在函数, 语句, 局部代码块中, 只在所属区域中有效
- 成员变量存在堆内存的对象中
- 局部变量存在栈内存的方法中
- 成员变量随着对象的创建而存在, 随着对象的消失而消失
- 局部变量随着所属区域的执行而存在, 随着所属区域的结束而释放
- 成员变量有默认初始化值
8. 局部变量没有默认初始化值
成员变量和静态变量区别
- 静态变量随着类的创建而创建, 随着对象的回收而释放
2. 成员变量随着对象的创建而创建, 随着类的消失而消失
- 静态变量可以直接被类调用
- 成员变量不可以直接被调用
- 静态变量存储在方法区(共享数据区)的静态区, 也叫对象的共有数据
6. 成员变量存储在对象的堆内存中, 也叫对象的特有数据
匿名对象
- 当对象对方法仅进行一次调用时, 就可以简化为匿名对象
构造函数
- 构建创造对象时调用的函数, 给对象初始化
this关键字
- this代表着所在函数所属对象的引用
- this也可以用于在构造函数中调用其他构造函数, 但应该放在第一行, 初始化动作应该最先执行
static关键字
1. static修饰的成员被所有的对象共享
- static优先于对象创建, static和类一起被创建
- static修饰的成员可以直接用类名调用
静态变量
- 当一个数据在对象中都是相同的时候且对象不做修改只做使用就可以使用静态
静态函数
- 当函数不需要访问对象中的特有数据也就是非静态成员变量时, 可以用静态修饰
静态
static{
}
- 随着类的加载而加载, 而且只执行一次, 用于给类初始化
构造代码块
{
}
- 随着对象的加载而加载, 创建几个对象调用几次, 给所有对象初始化
一个类不想被继承且实现
- 定义为abstract, 构造函数设为私有
单例设计模式
-
解决的问题: 保证一个类在内存中的对象唯一性
- 不允许其他程序new对象
- 在该类中创建一个本类实例
- 对外提供方法去获取该对象
-
步骤
- 私有化该类构造函数
- 通过new在本类中创建一个本类对象
- 定义一个公有静态方法, 返回对象
构造函数
- 在子类构造对象的时候, 父类构造函数也会执行, 子类构造函数默认会有一个隐式的super()去调用父类的空参的构造函数;
- 所有子类的构造函数默认都会访问父类的空参构造函数
子类实例化过程
- 子类先进行默认初始化再调用构造函数
- 通过super初始化父类内容时, 子类成员变量并未显示初始化
- 父类初始化完成
- 子类成员变量进行显示初始化
- 调用子类构造代码块
- 执行子类构造函数
多态
- Base b = new Super() 父类引用指向子类对象
-
成员变量:
- 编译时参考父类引用
- 运行时也参考父类引用
-
成员函数:
- 编译时参考父类引用
- 运行时参考子类对象
-
静态函数(不需要对象, 直接使用类调用, 所以其实不涉及多态):
- 编译时参考父类引用
- 编译时参考父类引用
异常
-
一般不可以处理的 Error
- 由JVM抛出的严重性的问题, 一般不予解决而是直接修改源码
-
可以处理的 Exception
- 编译时检查异常, Exception和其子类, 除RuntimeException
- 运行时异常, RuntimeException和其子类
- 自定义异常要么继承Exception, 要么RuntimeException
- throw用来引发异常, throws用来声明异常
多线程
-
创建线程方式
-
继承Thread类
- 定义一个类继承Thread类
- 重写Thread类的run方法
- 实例化Thread子类
- 使用start方法开启线程并调用run方法
-
实现Runnable接口
- 定义一个类实现Runnable接口
- 实现Runnable接口中的run方法
- 实例化Thread类并传入该类实例作为构造函数的参数
- 使用start方法开启新线程
-
-
多线程因为处理机的随机分配, 可能会出现安全问题
-
同步代码块
- 语法
synchorized(对象){需要同步的代码块}
- 同步好处: 解决线程安全问题
- 同步弊端: 降低效率, 需要判断一次同步锁
- 同步前提: 多个线程使用同一个锁
-
同步函数
- 在函数前加一个synchorized修饰符
- 和同步代码块区别在于需要同步的范围不同, 想清楚需要同步的范围之后再决定用同步代码块和同步函数
- 同步函数带的锁就是调用该函数的对象
-
-
多线程间通讯
使用等待唤醒机制
涉及的方法:- wait(): 线程处于冻结状态, 存储到线程池中
- notify():唤醒任意一个线程池中线程
- notifyAll(): 唤醒线程池中所有线程
-
wait和sleep区别
- wait可以传入一个时间, 释放执行权, 释放锁.
- sleep必须指定一个时间, 释放执行权, 不释放锁.
- setDaemon设置为守护线程, 当当前运行的所有线程为守护线程时, 虚拟机退出
- join方法, 线程执行join方法后会获得处理机, 并当前线程执行结束后才释放处理机
- yield方法, 线程会重新进入就绪状态
- setPriority方法设置线程的优先级 可传入MAX_PRIORITY, MIN_PRIORITY, NORM_PRIORITY三个线程静态字段
String
String
- 在字符串建立时, 内存中有一个字符串常量池(缓冲区), 创建字符串时, 在字符串常量池创建, 以后每次先寻找常量池中是否有字符串, 如果有直接指向即可, 不用重新创建字符串
- 使用new创建字符串时, 在堆中创建一个String对象.
StringBuffer
- 长度可变, 默认长度为16个字符
- 可以存储不同类型数据
- 可以修改字符串
-
拓展长度原理
1. 在内存中新建一个StringBuffer, 长度一般为原来的两倍- 将原数据全部拷贝到新StringBuffer内
StringBuilder
- 和StringBuffer类似, 不过StringBuffer同步, StringBuilder不保证同步
集合框架
List
- 有序, 元素都有索引, 可以重复
ArrayList
- 内部数据结构为数组, 非同步, 新增和删除效率低, 查找效率高
LinkedList
1. 内部数据结构为链表, 新增和删除效率高, 查找效率低, 非同步
Vector
- 同步, 查找, 新增和删除效率都低
Set
- 无序, 元素不允许重复
HashSet
- 内部数据结构为Hash表, 非同步
- 使用元素hashcode方法确定位置, 如果hashcode方法结果相同, 再通过equals方法确定是否相同
LinkedHashSet
- 在HashSet基础上实现了存取有序
TreeSet
- 内部数据结构为二叉树, 使用元素的自然顺序对元素进行排序, 非同步
- 对于自定义对象, 让元素自身具备比较功能, 应该实现Comparable接口, 覆盖compareTo方法进行排序.
- TreeSet排序第二种方法, 让集合自身具备比较功能, 创建一个类实现Comparator接口, 覆盖compare方法 并将其传入TreeSet的构造函数, 在比较器和自然排序时, 比较器优先级较高
泛型
- 规定了传入的参数类型, 避免转换类型的麻烦, 在编译时期检查
- 在运行时会将泛型进行擦除, 即class文件中没有泛型
- 当方法定义为静态时, 不能使用类上定义的泛型, 只能将泛型定义在方法上
泛型限定
- 泛型的上限, <? extend Obj>泛型能够传入Obj本身及其子类
- 泛型的下限, <?super Obj>泛型能够传入Obj本身及其父类
Map集合
- KeySet方法获取所有的键
- entrySet方法获取所有键值对
HashMap
- 内部数据结构为Hash表
- 非同步
- 允许键值对为null
HashTable
- 内部数据结构为Hash表
- 同步
- 不允许键值对为null
Propertites
- 用来存储键值对类型的配置文件, HashTable的子类
TreeMap
- 内部数据结构为二叉树
- 非同步
- TreeSet实际上就是使用的TreeMap
I/O流
输入和输出
- 外设-->内存: 输入流
- 内存-->外设: 输出流
字节流和字符流
- 字符流: 字节流先读取文本数据, 不直接操作, 而是先查询指定编码表
- 字节流: 直接读取文本数据
I/O流常用基类
-
字节流顶层基类
- InputStream
- OutputStream
-
字节流顶层基类
- Reader
- Writer
字符流缓冲区
- BufferedWriter
- BufferReader
Serizalizable接口
- 用于给被序列化的类加入ID号, 可手动指定ID号
- 被static修饰的变量不会被序列化, 返回的值是当前JVM的值, 而不是被序列化之后的值
- transient被其修饰的变量也不会被Serizalizable序列化
反射
定义
- 在运行状态中, 对于任意一个类都能获取到该类的属性和方法
- 对于任意一个对象实例, 都能调用任意一个方法或属性
通过反射获取Class对象
- 通过实例对象的getClass()获取Class对象
Person person = new Person("小米", 20);
Class clazz = person.getClass();
- 通过类静态成员.class获取对应的Class对象
Class clazz = Person.class;
- Class对象的forName()通过类名获取Class对象
Class clazz = Class.forName("Person");
通过反射获取类字段
// 创建Class对象
Class clazz = Class.forName("Person");
// 创建空参新实例
Object object = clazz.newInstance();
// 获取字段
Field field = clazz.getDeclaredField("age");
field.set(object, 20);
Object object1 = field.get(object);
System.out.println(object1);
通过以上代码无法获取或设置类中私有变量, 也不建议直接获取类中私有变量, 如果想要强行获取的话看下面代码
Class clazz = Class.forName("Person");
// 创建空参新实例
Object object = clazz.newInstance();
// 获取字段
Field field = clazz.getDeclaredField("age");
// 对私有字段的访问取消检查, 不建议使用
field.setAccessible(true);
field.set(object, 20);
Object object1 = field.get(object);
System.out.println(object1);
通过反射获取类中方法
// 通过反射获取class对象
Class clazz = Class.forName("Person");
// 通过getMethod方法获取指定名称的方法, 第二个参数传递参数类型, 参数为int则传递int.class, 其他类似, 空参则传递null
Method method = clazz.getMethod("paramMethod", String.class, int.class);
// 获取类实例
Object object = clazz.newInstance();
// 通过invoke方法调用方法
method.invoke(object, "九" + 9);
四大作用域
- pageContext: 生存周期最短, 当前页面加载结束即死亡
- request:
- session: 当前浏览器关闭死亡, 当到达一个最大时间时, 服务器才删除session, 并不一定在浏览器关闭时session立刻死亡 request.getsession()而不是response.getsession()理由: 客户端发送请求时, request会带上session头, 服务器再根据session头寻找对应session.
- application: 生存周期最长, 服务器关闭时才死亡
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。