文章内容来自看过各种大佬的解答后进过自己的思路理解后整理出来的,如有冒犯,请私聊或评论立马删除!
发出来只是为了方便自己实时观看,谢谢!
Java基础
什么时候会发生类的初始化
类的加载过程
1.类的加载(Load) 将类的class文件读入内存,并创建一个java.lang.Class对象 此过程由类加载器完成
2.类的链接(Link) 将类的二进制数据合并到jre中
1.验证:确保加载的类的信息符合jvm规范,没有安全方面的问题
2.准备:正式为类变量(static) 分配内存并设置类变量默认初始值阶段,在方法区中分配
3.解析:虚拟机常量池内的符号引用(常量名)替换为直接引用(地址)的过程。
3.jvm负责对类进行初始化
类的主动引用(一定会发生类的初始化)
-
虚拟机启动,初始化main方法所在的类
-
new一个类的对象
-
调用类的静态成员(除了final常量)和静态方法(类的初始化只会发生一次)
public class LoadingDemo { public static void main(String[] args) { A a = new A(); a = new A(); A b = new A(); //结果是 aAAA } } class A { static { System.out.println("a"); } public A() { System.out.println("A"); } }
-
使用java.lang.reflect包对类进行反射
-
初始化一个类 如果父类没有被初始化 则会先初始化父类
类的被动引用(不会发生类的初始化)
-
访问静态域时 只有真正声明这个域的类才会初始化–自雷引用父类静态变量 不会导致子类初始化
-
通过数组定义类引用,不会出发此类的初始化
-
引用常量不会出发此类的初始化(常量在链接阶段就存入调用类的常量池中了)
代理模式
代理模式可以在不修改被代理对象的基础上,通过扩展代理类,进行一些功能的附加与增强。值得注意的是,代理类和被代理类应该共同实现一个接口,或者是共同继承某个类
静态代理
将方法的调用交给代理类。一次只能代理一个接口实现类
动态代理
动态代理,只要实现了InvocationHandler产生了代理处理器,会根据不同的Proxy.newProxyInstance()所对应的加载器,接口,和代理器的代理对象,而代理不同的是实现类,不需要和静态代理每次只能代理一个接口实现类。
1.创建被代理的接口和类;
//接口
public interface TestService {
void test();
}
//实现类
public class TestServiceImpl implements TestService {
@Override
public void test() {
System.out.println("test");
}
}
2.创建InvocationHandler接口的实现类,在invoke方法中实现代理逻辑;
//代理
public class TestInvocationHandler implements InvocationHandler{
//目标对象
private Object target;
//构造方法
public TestInvocationHandler(Object target) {
super();
this.target = target;
}
// 参数分别对应为代理对象 、代理对象调用的方法、调用的方法中的参数
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
System.out.println("before test");
method.invoke(target,args);
System.out.println("after test");
return null;
}
}
3.通过Proxy的静态方法newProxyInstance( Clas