关键字
default:一般用来修饰接口中的方法。
interface Person {
default void show() {
System.out.println("this is show");
}
}
public:访问控制修饰符,公共的,允许外部访问。
private:访问控制修饰符,private成员只能在成员所属的class内被调用。
protected:访问控制修饰符,允许子类访问。
final:变量指针不可变。final 修饰变量,表示变量的值不可改变,此时该变量可被称为常量;final 修饰方法,表示方法不能被子类重写。
abstract:抽象的,可修饰方法和类。
- 抽象类:此类不能实例化,要求子类去继承。类和类之间如果具有相同的特征,将这些共同的特征提取出来,形成的就是抽象类;抽象类是无法实例化的,无法创建对象的,所以设计抽象类就是用来被子类继承的。
- 抽象方法:只能存在抽象容器中,要求子类去覆盖重写。
static:静态的用于定义类(仅限内部类)、方法、字段。属于对象共享的,可以直接通过类访问。
synchronized:同步。用于修饰方法。
基础数据类型
- byte 字节(8位)
- short 短整型(16位)
- int 整形(32位)
- long 长整形(64位)
- float 单精度浮点(32位)
- double 双精度浮点类型(64位)
- boolean 布尔类型
- char 字符(16位),业务场景下一般用String字符串类型,String类型本身是对char进行了封装。
基础类型,声明的变量是有默认值的,不允许为空。
封装类型
- Byte
- Short
- Integer
- Long
- Float
- Double
- Boolean
- Character
对基础类型的封装。将基础类型封装为类。封装类型声明的变量可以为空。
装箱拆箱
装箱和拆箱本质上是基础类型和封装类型的转换。装箱是指由基础类型转换为封装类型,拆箱是指由封装类型转换为基础类型。
// 装箱
Integer a = 100;
// 拆箱
int b = a;
运算符
算术运算符
+ 加法
- 减法
* 乘法
/ 除法
% 求余
++ 自增
-- 自减
关系运算符
== 等于
!= 不等于
> 大于
< 小于
>= 大于等于
<= 小于等于
位运算符
& 与运算符
| 或运算符
^ 异或运算符
〜 取反运算符
<< 左移
>> 右移
>>> 无符号右移
使用了位运算符,会将对应的类型的数据转换为二进制进行运算,得到二进制结果后再输出为对应类型的数据。
逻辑运算符
&& 逻辑与
|| 逻辑或
! 逻辑非
接口和类
接口
接口用 interface 标识:
public interface AnimalI {
// 接口方法
void eat();
}
函数式接口
使用@FunctionalInterface注解,声明一个支持lambda表达式的接口,只允许有一个未实现的方法,同时可以存在多个默认方法和静态方法,允许定义 java.lang.Object 里的 public 方法。
@FunctionalInterface
public interface TestServiceI {
// 未实现的方法只允许有一个
void sayHello();
// 支持静态方法
static void print() {
System.out.println("Task方法接口");
}
// 默认方法
default void toSayHello() {
return () -> {
try {
this.sayHello();
} catch (Exception var2) {
throw new UncheckedException(var2);
}
};
}
@Override
boolean equals(Object obj);
类
类用 class 标识:
public class Pig implements AnimalI{
@Override
public void eat() {
System.out.println("eat sth.");
}
}
每个类只能继承一个类,每个类可以实现多个接口。
泛型
定义一个泛型接口
// 泛型接口(在接口名后用符号<>声明一个泛型T)
public interface Supplier<T> {
/**
* 泛型方法(在方法上的返回类型直接使用泛型T)
*/
T get();
}
使用:
// 声明一个类SupplierImpl,并实现Supplier接口,泛型类型为String
public class SupplierImpl implements Supplier<String> {
/**
* 实现一个
* @return
*/
@Override
public String get() {
return "get方法";
}
}
// 实例化
Supplier<String> supplier = new SupplierImpl<String>();
匿名类快速实现:
Supplier<String> supplier = new Supplier<String>() {
@Override
public String get() {
return "get方法";
}
};
集合
List:有序列表
ArrayList 有序列表,基于数组实现的下标访问。具备数组的特性。(插入性能差,顺序读取性能,随机读取性能强)
LinkedList 基于链表实现的有序集合。具备链表的特性。(插入性能强,顺序读取性能强,随机读取性能差)
Set:去重列表
HashSet 基于哈希表做的无序列表,超快的查找速度。不支持排序,不支持FIFO.
TreeSet 排好序的去重列表。利用红黑树来实现,写入数据时根据对象的comparaTo进行排序。写入性能差些。
LinkedHashSet 在HashSet的基础上加上双向链表,支持FIFO,写入性能差些,较强的迭代性能。
Queue:队列
ArrayBlockingQueue 队列满时不允许入队,队列空时不允许出队
LinkedBlockingQueue 单向链表,头部有一把锁,尾部也有一把锁,支持同时出队和入队,查找中间元素时需要同时获取两把锁
PriorityBLockingQueue 优先级队列
DelayQueue 延迟队列
ConcurrentLinkedQueue volatie 关键字和cas实现的, 没有阻塞等待的效果。出现并发的时候靠自旋来解决的
SynchronousQueue 同步队列,最多只能存储一个元素,每一个put操作必须等待一个take操作,否则不能继续添加元素
Map
TreeMap 基于树实现的
HashMap 基于哈希表+树实现的
LinkedHashMap 在HashMap基础上补充了链表结构,保证了FIFO的特性。
ConcurrentHashMap 线程安全的,支持并发使用
ConcurrentSkipListMap 线程安全的,基于跳表实现。
IO
// 创建一个文件对象
File file = new File("/data/test.txt");
// 创建一个文件输出流,用于从内存中往文件输出数据
FileOutputStream outputStream = new FileOutputStream(file);
// 创建一个字节数组输入流,往内存中写入一个字符串字节
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream("这里是测试字符串".getBytes());
// 将输入流的数据输出到输出流,完成数据写入硬盘的操作
IOUtils.copy(byteArrayInputStream,outputStream);
// 关闭流
byteArrayInputStream.close();
outputStream.close();
异常
java报错主要分为两种:错误和异常。
错误是java程序无法处理的问题,会导致程序终止,例如内存溢出等。
异常是程序运行过程中出现了意料之外的事情,可以被捕获和处理。
异常捕获:
// 尝试捕获异常
try{
// 程序代码 可能会出现异常的代码
}catch(ExceptionName e1){
// Catch 块 用于处理异常
}finally {
// 无论是否异常最终都会执行的代码块
}
异常抛出:
throw new RuntimeException("RuntimeException");
多线程
// 创建一个任务
Runnable task = ()->{
System.out.println("任务执行完成");
};
// 创建一个线程对象,将任务作为初始化参数进行入参
Thread thread = new Thread(task);
// 执行任务,本质上仅仅是执行task.run()而已,并不会启动线程。
thread.run();
// 启动线程:向操作系统申请创建线程并执行run方法。java==>访问本地方法创建线程==>回调java的run方法执任务
thread.start();
FutureTask返回值
// 用lambda表达式快速创建任务
FutureTask<String> futureTask = new FutureTask<>(() -> {return "FutureTask";});
// 创建线程实例
Thread thread = new Thread(futureTask);
// 启动线程并执行任务
thread.start();
// 获取返回值,这里可能阻塞
String s = futureTask.get();
锁
synchronized:java语法支持的锁,由java虚拟机实现。
// 在方法上使用,作为范围在整个方法,多线程下同时只有一个线程能执行这个方法
public synchronized void start() {
// 代码块
}
// 以代码块的方式使用,作用范围在代码块,()可以理解为锁的唯一标识,从内存来理解就是锁存放的位置。
public void start() {
// 代码块
synchronized("myLock"){
// 代码块
}
// 代码块
}
// 多线程下,start 和 start2方法同一时刻只能有一个方法中的synchronized代码块被执行,
// 因为他们锁存放的位置一样,其中一个方法的synchronized拿到锁后,另一个方法的synchronized就拿不到了,因为被拿走了
public void start2() {
// 代码块
synchronized("myLock"){
// 代码块
}
// 代码块
}
ReentrantLock:用Java写的一个工具类,本质上是基于CAS实现
// 创建一个reetrantLock对象,非公平锁,
ReentrantLock reentrantLock = new ReentrantLock();
// 公平锁
reentrantLock = new ReentrantLock(true);
// 加锁
reentrantLock.lock();
try {
// 代码块
} catch (Exception e) {
} finally {
// 释放锁
reentrantLock.unlock();
}
原子类
AtomicInteger 常用方法:
- int addAndGet(int delta): 以原子的方式将输入的数值与实例中的值相加,并返回结果。
- boolean compareAndSet(int expect, int update): 如果当前值等于预期值,则以原子方式将当前值设置为更新的值。
- int getAndIncrement(): 以原子的方式将当前值加 1,注意,这里返回的是自增前的值,也就是旧值。
- void lazySet(int newValue): 最终会设置成newValue,使用lazySet设置值后,可能导致其他线程在之后的一小段时间内还是可以读到旧的值。
- int getAndSet(int newValue): 以原子的方式设置为newValue,并返回旧值。
线程安全集合
- ConcurrentHashMap
- ConcurrentLinkedDeque
- ConcurrentLinkedQueue
- ConcurrentSkipListMap
- ConcurrentSkipListSet
并发工具包
- CountDownLatch 计数锁,计数为零时唤醒
- CyclicBarrier 就绪锁,所有线程就绪后统一执行
- Semaphore 信号量锁,可用于限流。
线程池
创建线程池核心参数
- corePoolSize 核心线程数:一般是CPU逻辑核心数+1,加1是为了最大程度上能争抢完所有CPU。
- maxinumPoolSize 最大线程数:最大的线程数量,根据业务类型进行调整
- keepAliveTIme 最大空闲时间:可以理解为不干活的实际时间,根据业务调整
- workQueue 工作队列:来不及处理的任务会放在这里,根据业务进行调整
- threadFactory 创建线程的工厂:用于创建自定义线程
- handler 拒绝策略:工作队列满后拒绝新任务的策略
// 创建线程池,四个核心线程
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(4,10,20,TimeUnit.SECONDS,new LinkedBlockingQueue<>(50));
// 通过线程池来执任务
threadPoolExecutor.execute(()->{
// 代码块
});
// 执行有返回值的任务
Future<?> submit = threadPoolExecutor.submit(() -> {
// 代码块
});
// 获取返回值
Object value = submit.get();
注解
跟注释类似,它是用来代码来描述的一种方式,它可以在编译或者执行中被读取到。
- @Documented 包含在生成的文档中
- @Retention 生效时间,源码中、编译生效、运行时生效
- @Targget 作用目标:类、方法、接口、注解、字段…
- @Inherited 是否被继承获取
- @Repeatable 是否可以在一个声明上使用多次
声明一个注解@Convert
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.FIELD})
public @interface Convert {
/**
* 转换器
* @return
*/
Class< ? extends Converter> value() default DefaultConverter.class;
}
/**
* 声明一个转换器接口
* @param <T>
*/
public interface Converter<T> {
/**
* 转换方法
* @param t
* @return
*/
T convert(T t);
}
/**
* 声明一个默认的转换器接
* @param <T>
*/
public class DefaultConverter<T> implements Converter<T>{
@Override
public T convert(T t) {
return t;
}
}