JavaSE要点
1.包装类
拆箱和装箱:装箱时把基本数据类型包装为对象(包装类),拆箱是从包装类中获取基本数据类型:
https://www.cnblogs.com/dolphin0520/p/3780005.html
但是在jdk1.5之后提供自动装箱拆箱功能:
包装类:是让基本数据类型包装之后,可以向对象一样进行引用传递。java中的数据类型int,double等不是对象,无法通过向上转型获取到Object提供的方法,而像String却可以,只因为String是一个对象而不是一个类型。基本数据类型由于这样的特性,导致无法参与转型,泛型,反射等过程。为了弥补这个缺陷,java提供了包装类。java8种基本数据类型所对应的包装类:
其中number中提供6个常用方法,用于获取包装类中基本数据类型的功能:
注意:包装类的比较都通过equals来完成。
2.接口
基本常识:接口可以多继承,而类不可多继承。
抽象类和接口的区别:https://blog.csdn.net/qq_33098039/article/details/78075184
类的设计应该遵循的原则:先设计接口,紧接着是抽象类,最后才是实体类。
3.泛型
通配符:问题引入,先定义一个泛型
如果此时两个泛型msgA和msgB都需要调用静态方法fun。
像上面这样写会出现问题,虽然可以完成图中所示代码,但是如果在fun中再加一个setcontent的操作,如果在msgA中设置content为string类型,那么直接出错。这时会用到泛型通配符:
这时,接收类型也不知道是什么类型(Message<?>),如果修改则会出现报错,但是参数还是可以获得。只能允许获得,不能修改。
在“?”这个通配符中还提供了两个小的通配符:
注意:
上界的list只能get,不能add(确切地说不能add出除null之外的对象,包括Object)
下界的list只能add,不能get
原因:
上界 <? extend Fruit> ,表示所有继承Fruit的子类,但是具体是哪个子类,无法确定,所以调用add的时候,要add什么类型,谁也不知道。但是get的时候,不管是什么子类,不管追溯多少辈,肯定有个父类是Fruit,所以,我都可以用最大的父类Fruit接着,也就是把所有的子类向上转型为Fruit。
下界 <? super Apple>,表示Apple的所有父类,包括Fruit,一直可以追溯到老祖宗Object 。那么当我add的时候,我不能add Apple的父类,因为不能确定List里面存放的到底是哪个父类。但是我可以add Apple及其子类。因为不管我的子类是什么类型,它都可以向上转型为Apple及其所有的父类甚至转型为Object 。但是当我get的时候,Apple的父类这么多,我用什么接着呢,除了Object,其他的都接不住。
泛型方法:
首先了解一下工厂模式:https://www.jianshu.com/p/3b4f6175d6e9
4.访问控制权限
public>protected>default>private。default的特点是连子类都不能访问。
5.单例模式和多例模式
单例模式和多例模式首先就是构造方法私有化,同时提供静态方法返回对象。
单例模式:单例设计模式所解决的问题就是:保证类的对象在内存中唯一,比如说电脑中的回收站就是一个单例。单例模式分为饿汉式和懒汉式 https://www.cnblogs.com/kuangdaoyizhimei/p/4000953.html
多例模式:和单例模式相似,但是多例模式在实例化私有静态对象时,实例多个。
6.枚举
https://www.cnblogs.com/zhaoyanjun/p/5659811.html,此博客中自定义枚举的set方法没有意义,不可以给枚举重新赋值
7.异常
java异常处理流程:
1.在程序运行之中才会产生异常,而一旦程序执行中产生了异常之后,将自动进行指定类型的异常类对象实例化处理。
2.如果此时程序之中井没有提供有异常处理的支持,则会采用jvm默认异常处理方式,首先进行异常信息的打印,而后退出程序执行。
3.此时程序中如果存在有异常处理,那么这个产生的异常类的实例化对象将会被try语句所捕获。
4.try捕获到之后依次和catch中的异常类型进行匹配,如果与catch中的类型相同,那么用此catch进行异常的处理,如果没有任何的catch与之匹配,那么就表示该异常无法进行处理,此时交给jvm处理。
注意:在捕获多个异常时必须把大的异常放置在范围小的异常的后面。
throw:
手工抛出一个异常类:
throws:
throws这个是处理异常的一种方式 还有一种方式就是:try{}catch(Exception e){} 只不过这个throws是把异常交给调用者或着系统来处理,我们老师曾经有个很经典的比方:异常当作篮球的话,你有两种方式处理它,要么投篮,即是用try{}catch(){}来处理 一种是传球,即是用throws来处理 这里不能这样理解的,只能说把它交给别人。
面试题:throw和throws的区别?
throw: 是在代码块中使用的,主要用户手工进行异常对象的抛出。
throws:是在方法定义上使用的,表示将此方法中可能产生的异常明确的告诉给调用出,由调用处进行处理。
https://blog.csdn.net/weixin_38011265/article/details/79149313
一个非常常用的异常处理模式(将异常交给调用者处理):
面试题:RuntimeException和exception的区别?
RuntimeException是exception的子类。
RuntimeException标注的异常类不需要进行强制处理(指的是try catch finally),而exception标注的类必须进行强制性处理。
常见的RuntimeException:nullpointerexception(空指针异常),numberformatexception(数字格式异常),classcastexception(java强制类型转换异常),IllegalArgumentException:非法参数,ArrayIndexOutOfBoundsException:数组越界。
8.内部类
其中的匿名内部类,如果不使用匿名内部类:
这样写如果messageimpl只用一次,那么会非常的浪费空间。如果使用匿名内部类:
这样相当于直接把imessageimpl直接写在了iMessage的内部。
https://blog.csdn.net/zhao_miao/article/details/83245816#11__2
9.函数式编程(lambda表达式)
lambda:lambda使得代码更加的简便,lambda表达式主要用于替换掉只有SAM标准的匿名内部类(只有一个抽象方法的匿名内部类),所以lambda用于一个仅包含一个方法的接口,一个仅包含一个方法的接口。在Java SE8中,像这样的代码形式被称为“函数式接口”。
简单用法:
https://www.cnblogs.com/linlinismine/p/9283532.html
方法引用:
可以使一个方法有多个方法名字,但要求必须是函数式接口:
比如引用一个静态方法(string中的valueof方法):
引用某个实例化对象的方法(toUpperCase方法):
10.链表