Java语法学习反射
大纲
- 基本介绍
- class的介绍
- 类加载
- 获取类的结构信息
- 创建对象
- 爆破
具体案例
1. 基本介绍
流程图(程序在计算机的阶段)
反射的主要的类
这个提高效率不大
2. class的介绍
对于第三点:首先类只会加载一次,得到的class的对象,也只有一个,如果用反射两次得到class的对象,只是名字不同,地址本质上还是一个
常用方法
public static void main(String[] args) {
String classPath = "reflection.Cat";
try {
Class<?> aClass = Class.forName(classPath);
System.out.println(aClass);//获取这个对象是哪一个类
System.out.println(aClass.getClass());//获取运行对象
System.out.println(aClass.getPackage().getName());//获取包名
System.out.println(aClass.getName());//得到全路径
Object obj = aClass.newInstance();//得到对象
//进行强转
Cat cat = (Cat) obj;
System.out.println(cat);
Field name = aClass.getField("name");//获取成员(这个是公有)
System.out.println(name.get(cat));//获取指定对象的这个属性
//通过反射给指定对象属性赋值,遵守访问权限
name.set(cat,"花花");
System.out.println(name.get(cat));
//得到成员的集合,再遍历
Field[] fields = aClass.getFields();
for (Field field : fields) {
System.out.println(field.getName());
}
//得到构造器
Constructor<?> constructor = aClass.getConstructor(int.class,String.class);
System.out.println(constructor);
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchFieldException |
NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) throws ClassNotFoundException {
String classPath = "reflection.Cat";
//第一种:通过forName获取
Class<?> aClass1 = Class.forName(classPath);
//第二种:直接获取
Class<Cat> aClass2 = Cat.class;
//第三种:创建对象后,利用对象获取
Cat cat = new Cat();
Class<? extends Cat> aClass3 = cat.getClass();
//第四种:通过类的加载器来获取
ClassLoader classLoader = cat.getClass().getClassLoader();
Class<?> aClass4 = classLoader.loadClass(classPath);
}
拥有class对象的类
3.类加载
反射是动态加载,在使用时,只有运行执行到这段代码才会进行校验,
其它的静态加载,在编译的时候就会进行校验
加载:
验证:
准备:
注意:在该阶段对于静态常量就是固定值
解析:
初始化:
合并就是会直接在加载时进行,然后在底层进行优化
4.获取类的结构信息
5.创建对象
如果需要无参,可以直接newInstance
否则,先获得构造器,再进行处理(有访问权限需要爆破),再通过构造器创建对象,进行赋值
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class test {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
String className = "B";
Class<?> aClass = Class.forName(className);
Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(String.class);
declaredConstructor.setAccessible(true);
Object object = declaredConstructor.newInstance("李四");
}
}
class B{
private String name = "张三";
private int age = 18;
public B() {
}
private B(String name, int age) {
this.name = name;
this.age = age;
}
private B(int age) {
this.age = age;
}
private B(String name) {
this.name = name;
}
}
6.爆破
返回是以object接收的编译类型,实际运行类型还是方法返回的