加载
就是将class文件读入内存,并为之创建一个class对象,任何类被使用时,系统都会建立一个class对象
连接
加载时机
类加载器的概述
负责将 .class文件加载到内存中,并生成与之对应的Class对象,虽然我们不需要关心类加载机制,但了解这个机制能够更好的理解程序是如何运行的。
类加载器的分类
类加载器的作用
也被称为应到类加载器,负责Java核心类的加载
比如System,String等,在JDK中JRE的lib目录下 rt.jar文件中。
负责JRE的拓展目录中jar包的加载
在JDK中JRE的lib目录下 ext目录
负责JVM启动时加载来自Java命令的class文件,以及classpath环境变量所指定的jar包和类路径
public static void main(String[] args) throws ClassNotFoundException {
//通过全类名获取字节码对象,路径地址
Class clazz1 = Class.forName("reflect.Person");
//通过类名
Class clazz2 = Person.class;
//通过对象名
Person p = new Person();
Class clazz3 = p.getClass();
System.out.println(clazz1 == clazz2);
System.out.println(clazz2 == clazz3);
}
答案全是true
Constructor构造器方法
Class类的newInstance()方法是使用该类无参的构造函数创建对象,如果一个类没有无参的构造函数,就不能这样创建了,可以调用Class类的getConstructor(String.class,int.class)方法获取一个指定的构造函数,然后再调用Constructor类的newInstance(“马云”,18)方法创建对象
public static void main(String[] args) throws Exception {
//通过全类名获取字节码对象
Class clazz = Class.forName("com.Person");
//获取无参构造
//Person p = (Person) clazz.newInstance();
//获取有参构造
Constructor c = clazz.getConstructor(String.class,int.class);
//利用Class对象的newInstance方法创建一个类的实例
Person p = (Person) c.newInstance("马云",23);
System.out.println(p);
}
Field
1
.Class.getField(String)方法可以获取类中的指定字段(可见的)
2
.如果是私有的可以用getDeclaedField(“name”)方法获取,通过set(obj,“成龙”)方法可以设置指定对象上的字段的值
3
.如果是私有的需要先调用setAccessible(true)设置访问权限,用获取的指定字段get(obj)可以获取指定对象中该字段的值。
public static void main(String[] args) throws Exception {
//获取字节码对象
Class clazz = Class.forName("reflect.Person");
Constructor c = clazz.getConstructor(String.class,int.class);
//通过有参构造创建对象
Person p = (Person) c.newInstance("张三",23);
//Field f = clazz.getField("name"); //获取姓名字段
//f.set(p, "李四"); //修改姓名的值
//获取私有时暴力反射获取字段
Field f = clazz.getDeclaredField("name");
f.setAccessible(true); //取效私有权限
f.set(p, "李四");
System.out.println(p);
}
Method
Class.getMethod(String,Class...)和Class.getDeclaredMethod(String,Class...)方法可以获取类中指定的方法,调用invoke(Object,Object)可以调用该方法,Class.getMethod("eat") invoke(obj) Class.getMethod("eat",int.class) invoke(obj,10)
public static void main(String[] args) throws Exception {
Class clazz = Class.forName("reflect.Person"); //通过全类名获取
//获取带参构造
Constructor c = clazz.getConstructor(String.class,int.class);
Person p = (Person) c.newInstance("马云的爸爸",23);//通过有参构造创建对象
Method m = clazz.getMethod("eat");//获取方法
m.invoke(p);
Method m2 = clazz.getMethod("eat", int.class);
m2.invoke(p, 10);
}
public static void main(String[] args) throws Exception {
ArrayList list = new ArrayList<>();
list.add(111);
list.add(222);
//通过全类名获取字节码文件
Class clazz = Class.forName("java.util.ArrayList");
Method m = clazz.getMethod("add", Object.class);//获取add方法
m.invoke(list, "abc"); //添加abc字符串****
System.out.println(list);
}
已知类:
pakeage reflect.sus;
public class demo1{
public void run(){
System.out.println("welcome to sus!");
}
}
配置文件内容
reflect.sus.demo1
测试类
public static void main(String[] args) throws Exception {
//创建流读取配置文件xxx.properties
BufferedReader br = new BufferedReader(new FileReader("xxx.properties"));
//通过全类名路径获取字节码对象
Class clazz = Class.forName(br.readLine());
//通过字节码创建对象
DemoClass dc = (DemoClass) clazz.newInstance();
dc.run();
}
1
.在java的java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过这个类和这个接口可以生成JDK动态代理类和动态代理对象。
2.
JDK提供的代理只能针对接口做代理。
public interface Student {
public void login();
public void submit();
}
public class StudentImp implements Student {
@Override
public void login() {
System.out.println("学生登录");
}
@Override
public void submit() {
System.out.println("学生提交");
}
}
public class MyInvocationHandler implements InvocationHandler {
//声明一个对象
private Object target;
//创建一个带参的构造函数
public MyInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("权限校验");
//执行被代理的target对象的方法
method.invoke(target, args);
System.out.println("日志记录");
return null;
}
}
public class Test{
public static void main(String[] args) {
StudentImp si = new StudentImp();
si.login();
si.submit();
System.out.println("-------------------------------");
//new一个代理类
MyInvocationHandler m = new MyInvocationHandler(si);
Student s = (Student)Proxy.newProxyInstance(si.getClass().getClassLoader(), si.getClass().getInterfaces(), m);
s.login();
s.submit();
}
}