类型 | 存储字节 | 取值范围 |
---|---|---|
int | 4 | [-2^31, 2^31-1] |
short | 2 | [-2^15, 2^15-1] |
long | 8 | [-2^63, 2^63-1] |
byte | 1 | [-2^7, 2^7-1] |
float | 4 | (有效位6-7位) |
double | 8 | (有效位15位) |
char | 2 | [0, 2^16-1] |
boolean | 参考JVM规范 |
enum Size {
SMALL, MIDDLE, LARGE
}
Size size = Size.SMALL;
运算符 | 说明 |
---|---|
<< |
左移,低位补0 |
>> |
右移,高位填充符号位 |
>>> |
无符号右移,高位填充0 |
System.out.println(Arrays.toString(arr))
LocalDateTime
系列。
按值引用。
定义:将数据和行为组合在一个包中,对对象的使用者隐藏具体的实现方式。
意义:重用性和可靠性
定义:通过扩展一个类来建立另外一个类的过程
定义:一个对象变量,可指向多种实际类型的现象
动态绑定:在运行时能够自动选择适当的方法
1. 父类的【静态】:属性,代码块
2. 子类的【静态】:属性,代码块
3. 父类的【成员】:属性,代码块
4. 父类的构造方法
5. 子类的【成员】:属性,代码块
6. 子类的构造方法
说明:
【静态】:静态属性,静态代码块。按定义的先后顺序
【成员】:成员属性,构造代码块
主要理解Java的单继承即可。具体的区别其实意义不大,这个更多的看设计时抽象出来的结构。
具体见: 深入理解Java的接口和抽象类
熟悉语法,使用场景。
语法:(parameters) -> expression
,或(paras) -> { statements; }
使用案例:菜鸟教程
类型:成员内部类,局部内部类,静态内部类,匿名内部类。
有且仅有一个抽象方法的接口。
同类型:方法引用,lambda,函数式接口
自定义一个接口:
@FunctionInterface
interface GreetingService {
void sayMsg(String msg);
}
GreetingService gS = msg -> System.out.println(msg);
gS.sayMsg("hello");
API提供的函数式接口:见源码包java.util.function
参考:Java动态代理
运行时
Class, Method
等
角色:委托类、代理类。
实现解耦,可以在代理类进行过滤增强等处理,而无需修改委托类代码。例如对学生五折销售,对商人八折销售等。
/*
场景:销售。生产,商店。
*/
interface Sell {
void sell();
}
// 委托类
class Product implements Sell {
@Override
public void sell() {
System.out.println("生产商");
}
}
// 静态代理类
class Shop implements Sell {
private Product product;
// ToDo 构造器
@Override
public void sell() {
this.product.sell();
}
}
代理类,在运行时被创建的代理方式,即动态代理。
优点:对代理类的函数进行统一的处理。而不用修改每个静态代理类的代码。
假设场景:在上述静态代理类的sell方法内,执行product.sell前后都需要输出日志信息。如果只有一个方法sell
,很简单,如果有很多方法呢?每个方法都需要添加日志,较为繁琐。
接口:Sell
委托类:Product
中介类:class SellProxy implements InvocationHandler
Object invoke(Object proxy, Method method, Object[] args);
说明:InvocationHandler只有一个方法需要实现,即invoke
解释:调用代理类对象时,这个调用会转送到invoke方法中,代理类对象作为proxy参数传进去,参数method标识了我们具体调用的代理类的方法,args位方法的参数。如此,可在invoke中添加统一的处理。
// 接口:Sell
// 委托类:Product
// 终结类
class ProductProxy implements InvocationHandler {
private Object obj;
// ToDo 构造器(Object obj)
@Override
public Object invoke(Object proxy, Method method, Object[] args) {
// 调用前处理..
// 调用:实际是反射
Object res = method.invoke(obj, args);
// 调用后处理
return res;
}
}
需要实现接口,如Sell
。JDK动态代理
常见的还有CGLib,利用ASM开源包,通过修改其字节码生成子类来实现。
Error和RuntimeException
RuntimeException,是可以通过编码避免的异常。
Exception中除RuntimeException
编译器要求必须处理的异常,要么捕获,要么抛出。
class MyException extends Exception {..}
class MyException2 extends RuntimeException {..}
void func(T arg) throws Exception {..}
void func2(T arg) {
if (arg == null) {
throw Exception();
}
}
void func() {
try {
...
} catch (Exception e) {
...
// 可抛出:throw Exception;
}
}
常用于释放资源。
一种调试程序的方式,建议使用单元测试。
List<?> list = null;
List<? extends Number> list2 = null;
List<? super Manager> list3 = null;
..
? super Manager
虚拟机没有泛型。
了解桥方法(保持多态)。
作用:遍历。
说明:remove和next的搭配
实现 | 说明 |
---|---|
ArrayList | 默认容量10,扩容1.5倍 |
LinkedList |
实现 | 说明 |
---|---|
PriorityQueue | 默认容量11,扩容(2倍+2)或(1.5倍) |
ArrayQueue | 容量=(tail-head+cap)%cap |
ArrayDeque | 默认容量16,扩容2倍 |
LinkedList |
实现 | 说明 |
---|---|
HashSet | 允许一个null |
LinkedHashSet | |
TreeSet |
实现 | 说明 |
---|---|
HashMap | 默认容量16,扩容2倍,允许null键和值 桶由链表和红黑树实现 |
LinkedHashMap | Node添加前后指针,记录插入顺序 |
TreeMap | 红黑树。节点key+value+left+right+parent+color |
WeakHashMap | |
IdentityHashMap |
常见API的使用。
System.out.println();
Scanner sc = new Scanner(System.in);
File file = new File(path);
FileOutputStream fos = ..;
DataInputStream
ObjectInputStream
接口:Serializable
transient
:序列化跳过当前关键字修饰的属性。
说明:可通过重载readObject和writeObject方法实现序列化
具体:java的IO之适配器模式和装饰模式
字符流Reader/Writer,适配器: InputStreamReader
和OutputStreamWriter
字节流InputStream/OutputStream,装饰器:FilterInputStream
和FilterOutputStream
ServerSocket
Socket
常见的BIO,阻塞IO。
然后是NIO,非阻塞IO,基础:IO多路复用
详情见:Java NIO浅析 美团技术团队
最后是AIO,异步IO。
进程中一个单一顺序的控制流。
Thread
Runnable
Callable
新建:new Thread®
可运行:start
阻塞:试图获取内部的对象锁,失败,线程被阻塞(synchronized
)
等待:线程等待另一个线程通知调度器出现一个方法时,线程进入等待(wait或join,或j.u.c的Lock或Condition
计时等待:Thread.sleep、Object.wait、Thread.join、Lock.tryLock以及Condition.await
终止:run方法正常退出,或一个没有捕获的异常
优先级
中断标志位:静态的Thread.interrupted()
,检查当前线程是否被中断,回清除中断状态;成员方法isInterrupted()
说明:线程被阻塞,其他线程调用interrupt()中断当前线程,会抛出异常
守护线程
通过同步,实现存取的顺序访问
synchronized
ReentrantLock
monitor,略。
JMM模型:略
三大特性:原子性,可见性,有序性
情形描述:多个线程同时被阻塞,它们中的一个或全部都在等待某个资源释放。
死锁产生的四个必要条件:
如何解决死锁:synchronized,或Lock。
产生死锁的样例:可使用信号量,避免死锁(具体)
线程1
syn(A) {
syn(B) {
..
}
}
线程2
syn(B) {
syn(A) {
..
}
}
ThreadLocal
方法:void set(T t)和T get()
场景一:管理数据库连接Connection,保证当前线程操作的都是同一个Connection,保证事务
阻塞队列:BlockingQueue
ArrayBlockingQueue
:必须指定容量
LinkedBlockingQueue
:可指定容量,默认Integer.MAX_VALUE
DelayQueue
:无上限阻塞队列
PriorityBlockingQueue
:无上限
TransferQueue
高效的映射、有序集和队列:ConcurrentHashMap
、ConcurrentSkipListMap
、ConcurrentSkipListSet
、ConcurrentLinkedQueue
写数组:CopyOnWriteArrayList
Executors
:
newCachedThreadPool: 核心线程=1,最大线程=Integer.MAX_VALUE,存活时间60s,同步队列(线程间同步移交任务)
new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
newFixedThreadPool: 核心线程=最大线程,LinkedBlockingQueue(容量Integer.MAX_VALUE)
new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
newScheduledThreadPool: 核心线程=core,最大线程=Integer.MAX_VALUE
new ScheduledThreadPoolExecutor(corePoolSize);
newSingleThreadExecutor: 核心线程=最大线程=1,LinkedBlockingQueue(容量int.max)
new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
ThreadPoolExecutor
核心线程
工作队列:阻塞队列BlockingQueue
最大线程数量 & 工作线程
工作线程存活时间
饱和策略
AbortPolicy:默认。不执行任务,直接抛出运行时异常
DiscardPolicy:抛弃任务
DiscardOldestPolicy:抛弃head的任务,即最先入队的任务
CallerRunsPolicy:在调用execute的线程执行此任务,会阻塞入口
用户自定义策略:需实现RejectedExecutionHandler