类的加载器
类的加载
当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化。
l 加载
就是指将class文件读入内存,并为之创建一个Class对象。
任何类被使用时系统都会建立一个Class对象
l 连接
验证 是否有正确的内部结构,并和其他类协调一致
准备 负责为类的静态成员分配内存,并设置默认初始化值
解析 将类的二进制数据中的符号引用替换为直接引用(变量赋值)
l 初始化
就是我们以前讲过的初始化步骤
反射
Class类
获取Class的三种方式:
Person p=new Person();//自定义类
//1.通过Object类中的getClass方法获取
Class c1=p.getClass();
//2.通过类名获取
Class c2=Person.class;
//3.通过完整的包名加类名获取
Class c3=Class.forName("com.oracle.d03.Person");
Constructor通过反射获取构造方法:
getConstructors() //反射获取所有公共构造方法,返回个Constructor[]
getConstructor(Class<?>... parameterTypes) //反射获取某个指定参公共构造方法,
newInstance(参数) //通过反射获取的构造方法,创建对象,
例:
//获取某个公共的构造方法
Constructor con1=c.getConstructor(String.class,int.class);
//通过构造方法创建对象
Object obj=con1.newInstance("000",2);
System.out.println(obj);
getDeclaredConstructors() //获取所有构造方法(包含私有)
getDeclaredConstructor(Class<?>... parameterTypes) //获取某个指定参构造方法(包含私有)
setAccessible(boolean flag) //暴力反射,违反了面向对象的封装,所有不使用。
例:
//获取某个私有构造方法
Constructor cons=c.getDeclaredConstructor(String.class);
//暴力反射
cons.setAccessible(true);
Object obj=cons.newInstance("aaa");
Field通过反射获取成员变量
getFields() 获取所有公共变量
getField (String name) 获取某个公共成员变量
getDeclaredFields() 获取所有成员变量
getDeclaredField(String name) 获取某个成员变量
set(Object , 值) 方法,给获取的变量赋值
通过反射获取成员变量并赋值:
获取指定的成员变量(私有成员变量,通过setAccessible(boolean flag)方法暴力访问)
Field fields=c.getDeclaredField("age"); //获取指定成员变量
Person p=new Person(); //创建对象
fields.set(p, 18); //赋值
System.out.println(p);
Method通过反射获取成员方法:
getMethods() 获取所有public 修饰的方法
getMethods(String name , Class<?>... parameterTypes) 获取某个成员方法
newInstance(参数) 通过反射获取的方法,创建对象,
newInstance() Class类中方法,快速创建对象,只能调空参方法
invoke(Object obj , 参数) 调用当前Method代表的方法
例:
获取单个成员方法
Method method=c.getMethod("sleep",String.class);
Object p = c.newInstance(); //创建对象
method.invoke(p,"aa"); //调用
获取私有成员方法,步骤如下:
1. 获取Class对象
2. 获取构造方法
3. 通过构造方法,创建对象
4. 获取指定的方法
5. 开启暴力访问
6. 执行找到的方法
泛型擦除
程序编译后产生的.class文件中是没有泛型约束的,这种现象我们称为泛型的擦除。我们可以通过反射技术,来完成向有泛型约束的集合中,添加任意类型的元素
ArrayList<Integer> arr=new ArrayList<Integer>();
//通过ArrayList的字节码文件对象
Class c=arr.getClass();
//通过反射获取add方法
Method add=c.getMethod("add",Object.class);
add.invoke(arr, "aaa");
反射配置文件
读取Peoperties.txt文件中的数据,通过反射技术,来完成Person对象的创建
//明确配置文件的路径,IO字符输入流
FileReader fr=new FileReader("src/com/oracle/d02/config.Properties");
//创建Properties集合
Properties pro=new Properties();
//从配置文件中读取键值队到集合中
pro.load(fr);
//从集合中获取完整的包名加类名
String ClassName=pro.getProperty("ClassName");
//获取方法名
String MethodName=pro.getProperty("MethodName");
//通过反射获取字节码文件
Class c=Class.forName(ClassName);
//创建对象
Object obj=c.newInstance();
//获取方法
Method method=c.getMethod(MethodName);
//调用方法
method.invoke(obj);