反射
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法,这种动态获取、调用对象方法的功能称为java语言的反射机制。
应用:获取类的全部方法、属性、构造函数、特定方法
-
为什么有反射? 灵活
编译期(进行编译–javac)&运行期(运行)
动态代理、spring中的AOP
-
策略模式
abstract BaseStrategy.execute()
BaseStrategy.execute(){ //执行某种策略 }
源文件——》class文件——》内存
生成对象步骤 :编译期加载class文件、查找构造函数、通过构造函数创建对象
反射:
- 运行期加载class文件
Class Person = Class.forName("com.fan.Person");
Class Person1 = Class.forName("com.fan.Person");
//Person 和 Person1相等,Class只有一个
-
创建构造函数Person()
Constructor c = Person.getConstructor();
-
创建对象
Person p = (Person)c.newInstance();
-
通过CLass对象,得到Field(属性)对象
Field f = c.getField(""); Field f = c.getDeclaredField(""); //.setAccessible(true)
获得class对象的方式?
-
getClass()
Person p = new Person(); Class c = p.getClass();
-
.class
Class c = p.class();
-
Class.forName()
Class c = Class.forName();
-
BeanUtils作用?
-
单体服务、微服务(垂直分割)
-
服务层次划分(水平分割)
-
MVC 水平分层
视图层:VO(view)/ UO
应用层:DTO/Entity
领域层:Dominan Entity/VO(value)
基础设置层:PO(Persistent 持久层)
-
集合容器
ArrayList源码
elementData Object[]数组
-
.add()
elementdata ArrayList默认数组 ArrayList默认容量10(DEFAULT_CAPACITY=10)
minCapacity 最小容量
扩容:先计算原有长度,再右移一位,加上原有长度(例:原有2,扩容就是3)
第一次扩容elementData为0,minCapacity=10
取原数组elementData的长度
int oldCapacity = elementData.length;
新的长度为旧的长度加上旧的长度右移(一半)
int newCapacity = oldCapacity + (oldCapacity >> 1);
比较新的长度和minCapacity,如果minCapacity大于新的长度,把minCapacity长度赋值给newCapacity
if (newCapacity - minCapacity < 0) { // eg1:newCapacity=10 newCapacity = minCapacity;//minCapacity = 10 }
扩展数组长度,并将旧数组的数据复制到elementData
elementData = Arrays.copyOf(elementData, newCapacity);
-
get()
public E get(int index) { rangeCheck(index); //index下标 return elementData(index); }
rangeCheck()判断下标是否越界,如果超出抛异常
private void rangeCheck(int index) { if (index >= size) { throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } }
-
remove()
1.rangeCheck
2.counts(记录修改次数)
3.oldValue(修改的值)
4.numMoved = size - index -1(移动的数量)
5.arraycopy(elementData,index+1,elementData,index,numMoved)
6.将最后一位移除
// eg1:elementData中保存了{"a1","a2","a3","a4"},删除第一个元素,即:index=0 public E remove(int index) { /** 校验传入的参数index是否超出了数组的最大下标,如果超出,则抛出:IndexOutOfBoundsException异常*/ rangeCheck(index); modCount++; // eg1:String oldValue="a1" E oldValue = elementData(index); // eg1:numMoved=4-0-1=3 int numMoved = size - index - 1; if (numMoved > 0) { /** 从需要删除的index后一位开始到末尾的这部分数据,整体都向前移动一个元素。*/ System.arraycopy(elementData, index + 1, elementData, index, numMoved); } // 通知jvm将之前的最后一位元素进行垃圾回收 elementData[--size] = null; // clear to let GC do its work return oldValue; // 返回已被删除的元素 }
LinkList源码
-
继承AbstractSequentialList抽象类,遍历时更推荐顺序遍历(迭代器)。linkedlist同样有get(index)方法,但是他的底层实现是链表,每次调用get方法时,都会从链表的头或者尾部进行遍历,时间复杂度是O(index),arraylist(index)可以直接查找到,复杂度是O(1)。
-
实现了Linked接口
-
实现了Cloneable接口
-
实现了Deque接口
-
实现了Serializable接口,表示可以序列化(readObject(ObjectInputStream o)writeObject(ObjectOutputStream o))
-
六种辅助方法
void linkFirst(E e) void linkLast(E e) linkBefore(E e, Node<E> succ) E unlinkFirst(Node<E> f) E unlinkLast(Node<E> l) E unlink(Node<E> x)
-
LinkedLiist核心Node类
private static class Node<E> { E item; // 结点元素 Node<E> next; // 后置结点指针 Node<E> prev; // 前置结点指针 Node(Node<E> prev, E element, Node<E> next) { this.item = element; this.next = next; this.prev = prev; } }
泛型
内容持续更新中。。。。。。