本文共 4356 字,大约阅读时间需要 14 分钟。
目录
1. 一个类只能继承一个抽象类,但是可以实现多个接口;
2. 抽象类可以包含具体方法,接口中的所有方法都是抽象的;
3. 抽象类可以声明和使用字段;接口则不能,接口中的变量都是final类型的常量;
4. 抽象类中的方法的修饰符可以是public、protected、private或者default;接口中的方法只能是public(JDK7);
注意:在JDK8中,Java接口引入了一些新功能 — 默认方法和静态方法;在JDK9中,还可以在接口中使用private私有方法
5. 抽象类可以定义构造函数;接口不能
6. 抽象类主要用来抽象类别,接口主要用来抽象方法功能
关注事物的本质,用抽象类;关注一种操作,用接口
1. 如果想让一部分方法拥有默认实现,使用抽象类。
2. 如果想实现多重继承,必须使用接口。由于Java不支持多继承,子类不能够继承多个类,但可以实现多个接口。因此你就可以使用接口来解决它。
3. 如果基本功能在不断改变,那么就需要使用抽象类。如果不断改变基本功能并且使用接口,那么就需要改变所有实现了该接口的类。
基本类型 | 字节数 |
byte | 1 |
short | 2 |
int | 4 |
long | 8 |
float | 4 |
double | 8 |
char | 2 |
boolean | true/false |
List
1. 可存储重复对象;
2. 是一个有序集合,保存了每一个元素的插入顺序,输出顺序就是插入顺序;
3. 常见的实现类有ArrayList、LinkedList和Vector
Set
1. 不允许重复对象,只允许一个null元素
2. 无序容器,无法保证每个元素的存储顺序,TreeSet通过Comparator或者Comparable维护了一个排序顺序;
3. 常见的实现类有HashSet、LinkedHashSet和TreeSet,最流行的是基于HashMap实现的HashSet
Map
1. Map不是Collection的子接口或者实现类,Map和Collection同级,是一个接口
2. 以键值对的形式进行数据存储
3. 键不允许重复,允许null作为Map的键和值
4. TreeMap也通过Comparator或者Comparable维护了一个排序顺序
5. 常见的实现类有HashMap、TreeMap、LinckedHashMap和HashTable
(回答优缺点)
1. 经常使用索引对元素进行访问,使用ArrayList,经常对元素进行增加删除操作,使用LinckedList
2. 想让元素按照插入的次序进行有序存储,使用List
3. 想要保证元素的唯一性,使用Set
4. 想要使用键值对的形式进行数据存储,使用Map
1. ArrayList的底层是可变长数组,LinkedList的底层是链表(链表结构特征)
2. 经常随机访问数据,ArrayList更快,因为LinkedList要移动指针
3. 经常进行新增和删除操作,LinkedList更快,因为ArrayList要移动数据
LinkedList底层是一个双向链表,LinkedList的基本操作就是对双向链表的操作。
push()和pop()方法实现
改变元素的前驱节点和后驱节点的指向
可变长数组,初始容量为10,扩容后容量大概为原容量的1.5倍
如何实现自动扩容和缩容:
elementData = Arrays.copyOf(elementData, newCapacity);
总结:
1. copyOf()的实现是用的是arrayCopy();
2. arrayCopy()需要目标数组,对两个数组的内容进行可能不完全的合并操作;
3. copyOf()在内部新建一个数组,调用arrayCopy()将original内容复制到copy中去,并且长度为newLength,返回copy。
字节流:继承至InputStream、OutputStream,主要用于处理字节或二进制对象
字符流:继承至InputStreamReader、OutputStreamWriter,主要用于处理字符或字符串
区别:
一个字符对应两个字节,字节流存汉字,会出现乱码
音频视频歌曲图片:字节流
文件(中文):字符流
方法 | 用途 |
charAt() | 返回字符串该下标的字符 |
indexOf() | 返回指定字符第一次出现的字符串内的索引 |
subString() | 截取字符串,含头不含尾 |
valueOf() | 将其他类型转换为字符串类型 |
trim() | 去除字符串开头和结尾的空字符 |
split() | 字符串分割 |
toUpperCase()和toLowerCase() | 统一转换为大写或者小写 |
toString() | 转换为String类型 |
toCharArray() | 将字符串转换为字符数组 |
getBytes() | 将字符串转换为字节数组 |
compareTo()/compareToIngnoreCase() | 比较字符串 |
equals()/equalsIgnoreCase() | 比较 |
concat() | 拼接 |
int和Integer
JDK 1.5以后
Integer缓存:-128~127
sort(),默认情况下是自然排序,还可以设置比较排序
binarySearch(),二分查找
max()/min(),返回集合中最大/最小的元素的角标
reverse(),反转
swap(),将指定List集合中i元素和j元素进行交换
fill(),将集合中所有元素替换成新的元素
copy(),将所有元素从一个列表复制到另外一个列表中
shuffle(),随机置换(排序)
1. 可变与不可变
String类型的对象是不可变的,任何对String的改变都会引发新的String对象的生成
StringBuffer和StringBuilder都是可变的
2. 是否多线程安全
String是不可变的,线程安全
StringBuffer,对方法加了同步锁,或者对调用的方法加了同步锁,线程安全
StringBuilder,线程不安全
可以
null也是对象,可以作为键值
常见排序:冒泡、选择、快速、插入、归并、堆
内排序:排序期间数据对象全部存放在内存的排序
外排序:排序期间全部对象太多,不能同时存放在内存中,必须根据排序过程的要求,不断在内,外存间移动的排序
1. 静态代理
由程序员创建或特定工具自动生成源代码,也就是在编译时就已经将接口,被代理类,代理类等确定下来。在程序运行之前,代理类的.class文件就已经生成。
2. 动态代理
代理类并不是在Java代码中定义的,而是在运行时根据我们在Java代码中的“指示”动态生成的。相比于静态代理, 动态代理的优势在于可以很方便的对代理类的函数进行统一的处理,而不用修改每个代理类中的方法。
解释JDK动态代理和CGLIB动态代理
然后扯aop底层就是动态代理
1. 封装
通常认为封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口。面向对象的本质就是将现实世界描绘成一系列完全自治、封闭的对象。我们在类中编写的方法就是对实现细节的一种封装;我 们编写一个类就是对数据和数据操作的封装。可以说,封装就是隐藏一切可隐藏的东西,只向外界提供最简单的编程 接口。
2. 继承
继承是面向对象最显著的一个特性。继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。
优点
新的实现很容易,因为大部分是继承而来的
很容易修改和扩展已有的实现
缺点
打破了封装,因为基类向子类暴露了实现细节
白盒重用,因为基类的内部细节通常对子类是可见的
当父类的实现改变时可能要相应的对子类做出改变
不能在运行时改变由父类继承来的实现
3. 多态
多态性是指允许不同子类型的对象对同一消息作出不同的响应。简单的说就是用同样的对象引用调用同样的方法但是做了不同的事情。多态性分为编译时的多态性和运行时的多态性。如果将对象的方法视为对象向外界提供的服务,那么运行时的多态性可以解释为:当 A 系统访问 B 系统提供的服务时,B 系统有多种提供服务的方式, 但一切对 A 系统来说都是透明的。方法重载(overload)实现的是编译时的多态性(也称为前绑定),而方法重写 (override)实现的是运行时的多态性(也称为后绑定)。
运行时的多态是面向对象最精髓的东西,要实现多态需要做 两件事:1. 方法重写(子类继承父类并重写父类中已有的或抽象的方法);2. 对象造型(用父类型引用引用子类型对 象,这样同样的引用调用同样的方法就会根据子类对象的不同而表现出不同的行为)
4. 抽象
抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面。抽象只关注对 象有哪些属性和行为,并不关注这些行为的细节是什么。
static可以修饰成员变量、成员方法、代码块、内部类
1. 父类的静态成员变量或者静态代码块
2. 子类的静态成员变量或静态代码块
3. 父类非静态成员变量以及非静态代码块
4. 父类构造方法被加载
5. 子类非静态成员变量以及非静态代码块
6. 子类构造方法被加载
编译后泛型就不存在了(泛型擦除),可通过反射来获取泛型信息
在Java中,final关键字可以用来修饰类、方法和变量(包括成员变量和局部变量)。
1. 修饰变量,被final修饰的变量必须要初始化,赋初值后不能再重新赋值
这个变量被初始化后便不可改变,这里不可改变的意思对基本类型来说是其值不可变,而对于对象变量来说其引用不可变,即不能再指向其他的对象
2. 修饰方法,被final修饰的方法代表不能重写
3. 修饰类,被final修饰的类,不能够被继承