知识要点

反射

类的加载过程

1.加载

jvm将类的字节码文件(.class)加载道内存中,创建class对象

2.链接

2.1确保字节码规范

2.2将静态变量加载到内存并赋默认值

2.3将符号引用转化为直接引用

3.初始化

加载静态代码块(static{})和静态变量显示赋值

实现反射的三种方式:

例:class User {public User(){}}

1.Class.forName(全限定路径名) class.forName("xxx.xxx.xxx.User");

2.类名.class User.class;

3.对象名.getClass() User user = new User(); user.getClass();

通过反射实例化的两种方式:

Class<User> clazz = User.class;

1.User user = clazz.newInstance(); // 获取无参构造器并且实例化 注:现已过时

2.clazz.getConstructor()或者clazz.getDeclaredConstructor()

Constructor<User> noArgConstructor = clazz.getConstructor(); // 仅获取构造器

noArgConstructor.newInstance(); // 实例化

泛型

提高代码的类型安全性、可重用性和可读性

在没有泛型前ArrayList集合通用的是object 这样在加入不同数据类型后,再取出来后需要类型转换,会倒置类型转换错误,有了泛型之后,规范了类型,在往集合里添加数据就直接会报类型错误 清晰的类型约束:直接声明数据类型,避免混乱的类型转换

例:ArrayList<String> array = new ArrayList<String>();

array.add("test");

array.add(123); // 在编译时就会报错,不用等到将数据加入进去后,再拿出来报运行时类型转换错误

ArrayList

非线程安全基于数组的集合

每次扩容是当前数组的1.5倍

查询和修改时可通过数组下标快速定位查询和修改

添加和删除时需要挪动多组数据,效率较慢

优化技巧:

1.在创建初始化时指定所需容量大小,避免多次扩容增加耗时

2.尽量批量操作,批量操作大于单个操作,批量操作会一下知道所需容量大小,减少扩容次数

3.尽量避免使用contains和remove,因为它的时间复杂度时O(n),contains需要遍历整个数组,而remove需要移动多个数据元素,影响耗时,高频繁操纵可用HashSet

LinkedList

基于双向链表的数组集合

适用于顺序查询,它只在头尾删除或插入时,时间复杂度接近O(1),其他增删时间复杂度也都是O(n)

它在查询指定索引元素时,会判断指定索引是否小于总元素数量的1/2,如果小于则会从前往后找,否则则会从后往前找,从而提高查询效率

它的添加默认是在尾部插入,时间复杂度接近O(1), 也可以指定索引插入,时间复杂度为O(n),因为它需要先找到要插入的指定的位置,然后再插入

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐