特意将零碎的知识点都整理出来,方便快速查阅。
一、重载与重写
- 重写:发生在子类中;与父类函数名相同,参数列表相同;返回值小于等于父类;访问权限大于等于父类;抛出异常小于等于父类;
- 重载:在用一个类中,方法名相同,参数列表不同,包括参数个数、类型和顺序;返回值和访问权性可以相同,也可以不同;(注意子类继承父类中的重载与重写的区分)
二、类中成员的初始化顺序
- 原则:
父类中静态成员和静态代码块,按照代码顺序依次加载;
子类中静态成员和静态代码块,按照代码顺序依次加载;
父类中实例成员和实例代码块,按照代码顺序依次加载;
父类中的构造方法开始初始化;
子类中实例成员和实例代码块,按照代码顺序依次加载;
子类中的构造方法开始初始化;
三、序列化与反序列化
- 序列化是将Java对象转化为字节序列,反序列化是将字节序列转化为Java对象;
- 序列化一方面实现数据的持久化,另一方面实现Java进程间对象通信
//Student类实现Serializable接口,transient关键字修饰属性不能序列化
public static void main(String[] args) {
Student s = new Student("lvziwei",22,"Xidian");
File file = new File("D://s.txt");
try {
file.createNewFile();
} catch (Exception e) {
e.printStackTrace();
}
try{
//序列化对象,输入输出流的判别标准为从内存中读为输出流,向内存中写为输入流
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(s);
oos.flush();
oos.close();
fos.close();
//反序列化对象
FileInputStream fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis);
Student ss = (Student) ois.readObject();
fis.close();
ois.close();
System.out.println(ss.getSchool() + "->" + ss.getAge() + "->" + ss.getName());
}catch(Exception e){
e.printStackTrace();
}
}
四、自动装箱与拆箱
- 装箱,将基本类型用它们对应的引用类型包装起来;拆箱,将包装类型转换为对应的基本类型;
- 编译器在编译期间,根据语法决定是否进行自动拆箱和装箱操作,减少常用数值的内存开销和创建对象开销;
// 下面以int为例解释
Integer i = 10; //自动装箱 Integer i = Integer.valueOf(10);
int i2 = i; //自动拆箱 int i2 = Integer.intValue(i);
Integer a = 10;
Integer b = 10;
System.out.println("i == b : " + (a == b)); //true
Integer a1 = 200;
Integer b1 = 200;
System.out.println("i1 == b1 : " + (a1 == b1)); //false
//原因解释 IntegerCache.low = -128 IntegerCache.high = 127
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
//自动装箱时,如果整数值在-128~127之间,则自动返回缓存值;
//不在此范围内,则自动新建对象;
// 下面以String为例解释
String str1 ="abc";
String str2 ="abc";
System.out.println(str2==str1); //输出为 true
System.out.println(str2.equals(str1)); //输出为 true
String str3 =new String("abc");
String str4 =new String("abc");
System.out.println(str3==str4); //输出为 false
System.out.println(str3.equals(str4)); //输出为 true
// 原因解释 "==" : 引用是否相同 "equals()" : 比较对象内容是否相同
// 字符串对象为不可改变对象,返回自身引用
五、Collection与Collections的区别
- java.util.Collection 是集合类的顶级接口,为集合对象的操作提供通用接口;Java类中有大量的具体实现;
- java.util.Collections 是一种包装类,包含有对集合操作的多种静态多态的方法;
六、序列号serialVersionUID
- 作用
确保版本间的兼容性,版本指的是Java类的版本; - 生成方式
默认生成方式,serialVersionUID = 1L;
由类名、接口名、成员方法和属性生成哈希值; - 作用原理
如果没有显示声明,则会自动生成,序列化操作后保存在文件中;反序列化时,JVM从文件中读取该值,与该类自动生成的值进行比较,相同则可以进行序列化;如果在序列化之后,反序列化之前,对类进行修改,则会重新生成新的值,此时不能进行反序列化;建议使用显示声明默认的序列化值;
七、Iterable和Iterator的区别
- 两者区别
Iterable是java.lang包中的接口,调用iterator()方法,返回Iterator对象;
Iterator是java.util包中的接口,具有hasnext()和next()方法;
Collection接口继承于Iterable接口; - 设计两者同时存在的原因
使用foreach(for增强)的类,均需要实现Iterable接口;
Collection的子类集合均是数据结构,而Iterator为迭代对象,设计者希望一种数据结构有多种迭代对象;
每次调用Iterable的iterator()方法,均会返回一个Iterator对象;
八、Map.Entry
- 概念
Map是Java的接口,Map.Entry是Map中声明的内部接口,保存Map的一个实体,其包含一个键值对;Map的entrySet返回一个类型为Map.Entry的集合;
九、Collection中的toArray()方法
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
Object[] i = list.toArray();
Integer[] i = list.toArray();// 错误,只能转换为Object类型
Integer[] ii = list.toArray(new Integer[0]);// 新建的数组长度随意,仅提供数组类型即可
}
十、Java的跨平台性
- Java由与平台无关的编译器生成字节码文件(.class文件),由与平台相关的解析器(不同平台的JVM)解析执行,来实现跨平台;
十一、switch支持的数据类型
- switch支持byte、short、int和char四种基本类型,枚举和String类型;
同时因为自动拆箱机制,支持四种基本数据类型的包装类;
public class TypeTest {
public static void main(String[] args) {
switch (new Integer(1)) {
case 0:
System.out.println("The num is : 0");
break;
case 1:
System.out.println("The num is : 1");
break;
default:
System.out.println("The num is null");
break;
}
}
}
The num is : 1
// 基于Jclasslib查看字节码文件
0 new #16 <java/lang/Integer>
3 dup
4 iconst_1
5 invokespecial #18 <java/lang/Integer.<init>>
8 invokevirtual #21 <java/lang/Integer.intValue> //此处实现自动拆箱,调用intValue方法
11 tableswitch 0 to 1 0: 32 (+21)
1: 43 (+32)
default: 54 (+43)
32 getstatic #25 <java/lang/System.out>
35 ldc #31 <The num is : 0>
37 invokevirtual #33 <java/io/PrintStream.println>
40 goto 62 (+22)
43 getstatic #25 <java/lang/System.out>
46 ldc #39 <The num is : 1>
48 invokevirtual #33 <java/io/PrintStream.println>
51 goto 62 (+11)
54 getstatic #25 <java/lang/System.out>
57 ldc #41 <The num is null>
59 invokevirtual #33 <java/io/PrintStream.println>
62 return
十二、JUC原子类
在原子类的源码中,涉及到unsafe类的诸多操作;
十三、小数计算精度
不同数值类型间的计算,存在着类型转换和信息丢失的问题;
Java不同数值间类型转换及信息丢失问题float和double类型的小数计算,会出现精度丢失问题,原因在于十进制小数在转换为二进制小数时的精度问题;
Java中小数计算精度问题
Java中解决精度丢失的常用问题
Java集合系列