1、static final区别
相同点
都可以修饰类、方法、成员变量。
都不能用于修饰构造方法。
static 可以修饰类的代码块,final 不可以。
static 不可以修饰方法内的局部变量,final 可以。
static:
static 修饰表示静态或全局,被修饰的属性和方法属于类,可以用类名.静态属性 / 方法名 访问
static 修饰的代码块表示静态代码块,当 Java 虚拟机(JVM)加载类时,就会执行该代码块,只会被执行一次
static 修饰的属性,也就是类变量,是在类加载时被创建并进行初始化,只会被创建一次
static 修饰的变量可以重新赋值
static 方法中不能用 this 和 super 关键字
static 方法必须被实现,而不能是抽象的abstract
static 方法不能被重写
final:
- final 修饰表示常量、一旦创建不可改变
- final 标记的成员变量必须在声明的同时赋值,或在该类的构造方法中赋值,不可以重新赋值
- final 方法不能被子类重写
- final 类不能被继承,没有子类,final 类中的方法默认是 final 的
2、throws、throw、try、catch(继续执行)、finally 用法区别
Java异常处理主要通过5个关键字控制:try、catch、throw、throws和finally。
try的意思是试试它所包含的代码段中是否会发生异常;而catch当有异常时抓住它,并进行相应的处理,使程序不受异常的影响而继续执行下去;
throw是在程序中明确引发异常;
throws的作用是如果一个方法可以引发异常,而它本身并不对该异常处理,那么它必须将这个异常抛给调用它的方法;
finally是无论发不发生异常都要被执行的代
关键字:throw,throws,try和catch的用法如下:
1、throws出现在方法的声明中,表示该方法可能会抛出的异常,允许throws后面跟着多个异常类型
2、throw出现在方法体中,用于抛出异常。当方法在执行过程中遇到异常情况时,将异常信息封装为异常对象,然后throw。
3、try出现在方法体中,它自身是一个代码块,表示尝试执行代码块的语句。如果在执行过程中有某条语句抛出异常,那么代码块后面的语句将不被执行。
4、catch出现在try代码块的后面,自身也是一个代码块,用于捕获异常try代码块中可能抛出的异常。catch关键字后面紧接着它能捕获的异常类型,所有异常类型的子类异常也能被捕获。
3、Error和Exception、RuntimeException和非RuntimeException的区别
① 异常的继承结构:基类为Throwable,Error和Exception继承Throwable,RuntimeException和IOException等继承Exception,具体的RuntimeException继承RuntimeException。
② Error和RuntimeException及其子类成为未检查异常(unchecked),其它异常成为已检查异常(checked)。
4、abstract、interface区别
一、interface与abstract的相同点:
1、都是没有具体实现,需要继承类进行实现;
2、无法直接调用;
二、interface和abstract的区别:
1、interface无构造方法,abstract类可以有构造方法;
2、abstract类中可以有普通成员变量,interface 只有抽象方法;
3、abstract类的访问类型可以是public或是protected,但interface默认的访问类型就是public abstract
4、一个类可以实现多个interface,但只能继承一个abstract类;
5、list、array、arraylist区别
5.1 Array、List的区别
Array—是基于索引(index)的数据结构,它使用索引在数组中搜索和读取数据是很快的。Array获取数据的时间复杂度是O(1),但是要删除数据却是开销很大
的,因为这需要重排数组中的所有数据
List—是一个有序的集合,可以包含重复的元素,提供了按索引访问的方式,它继承Collection。
List有两个重要的实现类:ArrayList和LinkedList
5.2 Array和ArrayList的区别
不同点:
(1)Array类型的变量在声明的同时必须进行实例化(至少得初始化数组的大小),而ArrayList可以只是先声明。
如:
int[] array = new array[5];
或 int[] array = {1,2,3,4,5};
或 ArrayList myList = new ArrayList();
这些都是合法的,而直接使用 int[] array;是不行的。
(2) Array只能存储同构的对象,而ArrayList可以存储异构的对象。
同构的对象:指类型相同的对象,若声明为int[]的数组就只能存放整形数据,string[]只能存放字符型数据,但声明为object[]的数组除外。
异构的对象:指任何不同类型的对象(因为它里面存放的都是被装箱了的Object型对象,实际上ArrayList内部就是使用"object[] _items;"这样一个私有字段来封装对象的)。
(3) 在CLR托管对中的存放方式
Array是始终是连续存放的,而ArrayList的存放不一定连续。
(4)初始化大小
Array对象的初始化必须只定指定大小,且创建后的数组大小是固定的。
ArrayList的大小可以动态指定,其大小可以在初始化时指定,也可以不指定,也就是说该对象的空间可以任意增加。
(5) Array不能够随意添加和删除其中的项,而ArrayList可以在任意位置插入和删除项。
相同点:
(1) 都具有索引(index),即可以通过index来直接获取和修改任意项。
(2)他们所创建的对象都放在托管堆中。
(3) 都能够对自身进行枚举(因为都实现了IEnumerable接口)。
5.3 ArrayList和List的区别
不同点:
(1)在编程语言中ArrayList类是.Net Framework提供的用于数据存储和检索的专用类。List 类可以简单视之为双向连结串行,以线性列的方式管理物件集合。List类是ArrayList类的泛型等效类。
(2)ArrayList可以插入不同类型的数据,而List不能。ArrayList会把所有插入其中的数据都当作为object类型来处理,这其中存在装箱与拆箱的操作,会对系统造成性能上的损耗。List需要声明其数据的对象类型,声明后插入其他类型数据就会报错,且不能通过编译。
(3)在使用ArrayList中的数据来处理问题的时候,很可能会报类型不匹配的错误,即ArrayList不是类型安全的。而List已经声明过其数据的对象类型,是类型安全的,避免了类型安全问题与装箱拆箱的性能问题。
(4)ListArray就可以被构造。而List不能被构造,但可以为List创建一个引用。
相同点:
(1)ArrayList与List都继承了IList接口,可以很方便的进行数据的添加,插入和移除,且List的大部分用法都与ArrayList相似。
5.4扩展资料
5.4.1、List泛型
通过允许指定泛型类或方法操作的特定类型,泛型功能将类型安全的任务从程序员转移给了编译器。不需要编写代码来检测数据类型是否正确,因为会在编译时强制使用正确的数据类型。减少了类型强制转换的需要和运行时错误的可能性。泛型提供了类型安全但没有增加多个实现的开销。
5.4.2、装箱与拆箱的概念:
(1)装箱:就是将值类型的数据打包到引用类型的实例中 。
(2)拆箱:就是从引用数据中提取值类型 。
(3)装箱与拆箱的过程是很损耗性能的。
6、List、Set、Map 之间的区别是什么?
List、Set、Map 的区别主要体现在两个方面:元素是否有序、是否允许元素重复。
三者之间的区别,如下表:
7、lock和synchronized区别
1.Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现;
2.synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而Lock在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象,因此使用Lock时需要在finally块中释放锁;
3.Lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不能够响应中断;
4.通过Lock可以知道有没有成功获取锁,而synchronized却无法办到。
5.Lock可以提高多个线程进行读操作的效率。(可以通过readwritelock实现读写分离)
6.性能上来说,在资源竞争不激烈的情形下,Lock性能稍微比synchronized差点(编译程序通常会尽可能的进行优化synchronized)。但是当同步非常激烈的时候,synchronized的性能一下子能下降好几十倍。而ReentrantLock确还能维持常态。
7.synchronized不如lock灵活。Lock和synchronize都是默认使用非公平锁的。如果不是必要的情况下,不要使用公平锁
8.总的来说,一般只要不是需要lock的灵活性,还是推荐使用synchronized,毕竟synchronized 在JDK1.6后,被优化加强了很多。
8、拦截器、过滤器、监听器区别
过滤器和拦截器的区别:
①拦截器是基于java的反射机制的,而过滤器是基于函数回调。
②拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
④拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
⑤在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
⑥拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。
触发时机
有个专业词语叫触发时机
1.过滤器和拦截器触发时机不一样:
过滤器是在请求进入容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前。
总结:过滤器包裹住servlet,servlet包裹住拦截器。
监听器
springMVC监听器主要的作用就是spring容器启动的时候加载一些数据,最常用的功能就是开发权限系统的时候,当监听器启动的时候,从数据库加载权限url。
9、VO,BO,PO,DO,DTO的区别
VO(Value Object)值对象
VO就是展示用的数据,不管展示方式是网页,还是客户端,还是APP,只要是这个东西是让人看到的,这就叫VO
VO主要的存在形式就是js里面的对象(也可以简单理解成json
DTO(Data Transfer Object)数据传输对象
这个传输通常指的前后端之间的传输
DTO是一个比较特殊的对象,他有两种存在形式:
在后端,他的存在形式是java对象,也就是在controller里面定义的那个东东,通常在后端不需要关心怎么从json转成java对象的,这个都是由一些成熟的框架帮你完成啦,比如spring框架
在前端,他的存在形式通常是js里面的对象(也可以简单理解成json),也就是通过ajax请求的那个数据体
这也是为什么把他画成横跨两层的原因
这里可能会遇到个问题,现在微服务盛行,服务和服务之间调用的传输对象能叫DTO吗?
我的理解是看情况
DTO本身的一个隐含的意义是要能够完整的表达一个业务模块的输出
如果服务和服务之间相对独立,那就可以叫DTO
如果服务和服务之间不独立,每个都不是一个完整的业务模块,拆开可能仅仅是因为计算复杂度或者性能的问题,那这就不能够叫做DTO,只能是BO
VO和DTO的区别
主要有两个区别
一个是字段不一样,VO根据需要会删减一些字段
另一个是值不一样,VO会根据需要对DTO中的值进行展示业务的解释
PO(Persistant Object)持久对象
PO比较好理解
简单说PO就是数据库中的记录,一个PO的数据结构对应着库中表的结构,表中的一条记录就是一个PO对象
通常PO里面除了get,set之外没有别的方法
对于PO来说,数量是相对固定的,一定不会超过数据库表的数量
等同于Entity,这俩概念是一致的
BO(Business Object)业务对象
BO就是PO的组合
简单的例子比如说PO是一条交易记录,BO是一个人全部的交易记录集合对象
复杂点儿的例子PO1是交易记录,PO2是登录记录,PO3是商品浏览记录,PO4是添加购物车记录,PO5是搜索记录,BO是个人网站行为对象
BO是一个业务对象,一类业务就会对应一个BO,数量上没有限制,而且BO会有很多业务操作,也就是说除了get,set方法以外,BO会有很多针对自身数据进行计算的方法
为什么BO也画成横跨两层呢?原因是现在很多持久层框架自身就提供了数据组合的功能,因此BO有可能是在业务层由业务来拼装PO而成,也有可能是在数据库访问层由框架直接生成
很多情况下为了追求查询的效率,框架跳过PO直接生成BO的情况非常普遍,PO只是用来增删改使用
BO和DTO的区别
这两个的区别主要是就是字段的删减
BO对内,为了进行业务计算需要辅助数据,或者是一个业务有多个对外的接口,BO可能会含有很多接口对外所不需要的数据,因此DTO需要在BO的基础上,只要自己需要的数据,然后对外提供
在这个关系上,通常不会有数据内容的变化,内容变化要么在BO内部业务计算的时候完成,要么在解释VO的时候完成
OK,到这里这些关系基本就理清楚了
等等,DO是什么
DO呢,标题不是还有个DO么?
上面这些概念基本上已经涵盖了全部的流程,DO只是跟其中一个概念相同
但是跟哪个概念相同呢?
现在主要有两个版本
一个是阿里巴巴的开发手册中的定义
DO( Data Object)这个等同于上面的PO
另一个是在DDD(Domain-Driven Design)领域驱动设计中
DO(Domain Object)这个等同于上面的BO