1.基本数据类型
- 基本数据类型 数值型(byte,int,short,long) 字符型(char) 布尔型(boole)
- 引用数据类型(类、接口、数组) 2.内存分析
- 栈 存放局部变量 先进后出,自下而上存储 方法执行完毕,自动释放空间
- 堆 存放new出来的对象 需要垃圾回收器来回收
- 方法区 存放:类的信息(代码)、static变量、字符串常量等 3.构造函数
- 创建对象的时默认会调用构造方法来创建对象。
- 创建完类后,如果没有手动调用构造方法,会有一个无参的构造方法供调用
- 方法名必须跟类的名字保持一致
- 没有返回值 4.重载
- 在一个类中可以包含多个重名的方法,但是方法的参数列表不能相同 5.this
- 表示当前对象本身,更准确的说代表当前对象的一个引用
- 用处:当参数名跟成员变量保持一致时,使用this表示对象的值 6.static关键字
- 静态成员变量或叫类变量
- 可以使用对象名或者类名直接调用
- 存在方法区而不是堆中
- 在创建对象之前被初始化,或者说在类被载入之前进行初始化
- 所以不能再静态方法中调用非静态方法,反之可以
- 不用以任何方式引用this和super关键之
- 静态变量被所有的对象共享,属于公共变量
- 一般工具类中的方法定义为static
- 主函数是静态方法 抽象方法、抽象类
- abstract
- 抽象类
- 不能实例化,即不能new
- 抽象类中的某些方法需要子类进行更丰富的实现,父类实现没有意义,此时可以 将抽象类中的方法定义为抽象方法,没有具体的实现,只包含方法名、返回值、 参数列表、访问修饰符
- 子类在继承抽象父类时,必须将父类中的抽象方法进行实现或将子类也定义为抽象类
- 抽象方法
- 抽象方法没有方法体
- 抽象方法必须在子类中被实现,除非子类是抽象类 接口
- java只能单继承,如果拥有多个父类时,可以考虑用接口实现
- 用法
- interface修饰
- 可以包含多个方法,且方法跟抽象类中的抽象方法一致
- 子类实现接口使用implement关键字
- 接口特征
- 接口中的所有方法都是抽象方法,不能包含方法的实现。默认省略public abstract
- 接口中的所有方法和常量无论是否添加public,默认的访问修饰权限 有且只有一个:public
- 接口不能被实例化
- 接口的子类必须要实现接口中的所有方法
- 子类可以实现多个接口
- 接口中的变量都是静态常量,如果变量没有使用static、final关键字修饰,也 表示静态常量,编辑器会自动补全
- 接口的使用
- 接口代表一种能力,接口可以定义多个方法,子类必须全部实现这些方法
- 只关心实现类有何能力,而不关心实现细节 StringBuffer和StringBuilder
- 可变字符串
- StringBuffer:线程安全
- StringBuilder:线程不安全 Map
- Map
- 特点key-value映射
- 基本操作
- 添加:put(k,v)
- 查询:isEmpty,size,containsKey,containsValue
- 删除:clear,remove
- Map.entery:表示的是K-V的映射关系,key和value是成组出现的
- HashMap
- 数据结构:哈希表。数组+链表(1.7) 数组+链表+红黑树(1.8)
- key无序 唯一(Set)
- value无序 不唯一(Collection)
- HashMap和HashTable的区别
- HashMap线程不安全,效率比较高。 HashTable线程安全(有synchronized关键字),效率低
- HashMap中key和value都可以为空,HashTable不允许为空
- LinkedHashMap
- 数据结构:链表
- 有序的HashMap 速度快
- TreeMap
- 数据结构:红黑树
- 有序 速度没有hash快
线程池
-
线程池实现原理
- 将任务提交和任务执行进行解耦,用户只需提供Runnable对象,将任务的运行逻辑提交到执行器(Executor)中,由Excutor框架完成线程的调配和任务的执行部分。线程池的运行主要分成两部分:任务管理,线程管理
-
为什么需要线程池
- 使用线程池可以重复利用已有的线程执行任务,避免线程在城建和销毁时造成的消耗
- 由于没有线程创建和消耗时的消耗,可以提高系统相应速度
- 通过过线程池可以对线程进行合理的管理,根据系统的承受能力调整可运行线程数
-
线程池分类
- ThreadPoolExecutor-设置线程数
- ScheduledThreadPoolExecutor-设置延时
- ForkJoinPool-设置允许并行数
-
线程的生命周期
- 新生-就绪-运行-死亡
- 阻塞
-
线程池的生命周期
- running:接受提交的任务,并且也能处理阻塞队列中的任务
- shutdown:关闭状态,不能接受新提交的任务,但却可以继续处理阻塞队列中 已保存的任务
- stop:不能接受新任务,也不处理队列中的任务,会中断正在处理任务的线程
- tidying:如果所有的任务都已终止了,有效线程为0,线程池进入该状态后会调用 terminater()方法进入terminated状态
- terminated:在terminated()方法执行完成后进入该状态,默认terminated() 方法中什么也没做
-
线程的创建ThreadPoolExcutor参数
- corePoolSize:核心线程个数
- maximumPoolSize:最大线程数
- keepAliveTime:空闲线程存活时间
- unit:时间单位
- workQueue:阻塞队列,用于保存任务的阻塞队列
- ArrayBlockingQueue
- LinkedBlockingQueue
- DelayQueue:当其指定的延迟时间到了,才能过从队列中获取到该元素
- PriorityBlockingQueue:基于优先级的阻塞队列
- SynchronousQueue
- threadFactory:,创建线程的工程类
- handler:饱和策略(拒绝策略) -abortPolicy
-
ArrayBlockingQueue和LinkedBlockingQueue的区别
- 队列中锁的实现不同
- ArrayBlockingQueue生成和消费用的事同一个锁,不能并行
- LinkedBlockingQueue锁是分离的,生成putLock,消费takeLock
- 队列大小初始化方式不同
- ArrayBlockingQueue基于数组,必须制队列的大小
- LinkedBlockingQueue基于链表,可以不指定队列大小,默认是integer.Max_Value
- 队列中锁的实现不同
-
拒绝策略
- ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出弃
- ThreadPoolExecutor.DiscardPolicy:丢弃任务,但不抛出异常
- ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
- ThreadPoolExecutor.CallerRunsPolicy:由调用线程直接处理该业务
-
线程池执行:execute方法执行逻辑
- 如果当前运行的线程少于corePoolSize,则会创建新的线程来执行新的任务
- 如果运行的线程个数等于或大于corePoolSize,则会将提交的任务放到阻塞队列workQueue中
- 如果当前workQueue队列已满的话,则会创建新的线程来执行任务
- 如果线程个数已经超过了maximumPoolSize,则会使用饱和策略来进行处理
-
execute和submit的区别
- execute 用于提交不需要返回值的任务
- submit方法用于提交需要返回值的任务。线程池会返回一个future类型的对象,通过这个 future对象可以判断任务是否执行成功,并且可以通过future的get()方法来获取返回值
-
线程池的关闭
- 可以通过shutdown和shutdownNow两个方法
- shutdown只是将线程池的状态设置为SHUTDOWN状态,然后中断所有没有正在执任务的线程
- shutdownNow首先将线程池的状态设置为STOP然后尝试停止所有正在执行和未执行任务的线程,并返回等待执行任务的列表
- 原理:遍历线程池中的所有线程,然后依次中断 final
- 可以通过shutdown和shutdownNow两个方法
-
可以修饰变量:表示变量的值不可变,被final修饰的变量必须被显式的指定初始值
-
可以修饰方法:表示方法不可以被重写
-
可以修饰类:表示类不可以被继承 object
-
getClass()反射
-
hashCode()计算对象哈希值
-
equals()
-
clone()
-
toString()
-
wait()线程等待
-
notify()线程唤起
-
finalxxxxxx ==和equals
-
==引用数据类型比较的是内存存放地址,除非是同一个new出来的 对象,否则比较的结果都是false。因为每new一次都会重新开辟堆内存空间
-
equals比较引用数据类型时,比较的是地址值是否相同 多态
-
对应同一个指令(调用同一个名称的方法),不同的对象给与不同的反应(不同方法实现)
-
同一个引用类型,使用不同的实例而执行不同操作
-
使用多态实现思路
- 编写父类
- 编写子类,子类重写父类方法
- 运行时,使用父类的类型,子类的对象 Pet pet = new dog();
-
实现多态的两种形式
- 使用父类作为方法参数
- 使用父类作为方法的返回值
-
多态的目的
- 为了提高代码的扩展性和维护性
- 方便代码逻辑的编写
-
instanceof
- 父类强转成子类前,要用instanceof运算符判断,否则可能编译不报错,运行时报错 java是值传递,还是引用传递 值传递 深拷贝、浅拷贝
-
仅拷贝基本数据类型变量的值和引用数据类型变量的地址值
-
完全拷贝一个对象,堆中的对象也会拷贝一份 java创建对象有哪几种方式
-
new创建新对象
-
通过反射机制
-
采用clone机制
-
通过序列化机制