类加载器+反射
1.类加载器的组成
- 负责将.class文件加载到内存中,并为之生成对应的Class对象。
- 虽然我们不需要关心类加载机制,但是了解这个机制我们就能更好的理解程序的运行
2.类初始化时机
1. 创建类的实例
2. 类的静态变量,或者为静态变量赋值
3. 类的静态方法
4. 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
5. 初始化某个类的子类
6. 直接使用java.exe命令来运行某个主类
3.反射
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意一个方法和属性;
这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
4.Class类
获取Class对象的三种方式
1.Person p=new Person(); Class c=p.getClass();
2.Class c2=Person.class;
3.Class c=Class.forName("Person");
5.通过反射获得类的构造方法
构造方法用Constructor类表示
Constructor con=c.getConstructor(参数.class);
getConstructor方法,获取公有的构造方法
getDeclaredConstructor方法,可获取私有的构造方法
getConstructors()方法,获取所有公共的构造方法
getDeclaredConstructors方法,获取所有公共和私有的构造方法
6.通过反射方式,获取构造方法,创建对象
调用Constructor中的newInstance方法,创建对象,明确参数值
7.通过反射方式,获取私有构造方法,创建对象
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { //获取类的字节码文件对象 Class c=Class.forName("com.oracle.demo01.Person"); //获取公共构造方法 Constructor con1=c.getConstructor(); System.out.println(con1); Constructor con2=c.getDeclaredConstructor(String.class,int.class); System.out.println(con2); //获取私有有参构造 Constructor con3=c.getDeclaredConstructor(int.class); System.out.println(con3); //调用方法创建对象 Person p1=(Person)con2.newInstance("张三",18); p1.eat(); //取消java语言检查 con3.setAccessible(true); //用私有构造方法对象创建Person对象/暴力反射 //破坏了程序的封装性,不推荐 Person p2=(Person)con3.newInstance(18); p2.eat(); // }
获取私有构造方法,调用构造方法类中的setAccessible,暴力反射,取消java语言检查
8.通过反射方法,获取成员变量,赋值并使用
调用Field类中的方法
getField(变量名)方法,获取公有的成员变量
getDeclaredField(String name)方法,获取指定的任何成员变量
public Field[] getFields() 获取所有public 修饰的变量
public Field[] getDeclaredFields() 获取所有的 变量 (包含私有)
public static void main(String[] args) throws NoSuchFieldException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException { //获取字节码文件对象 Class c=Class.forName("com.oracle.demo01.Person"); //获取成员变量对象 Field f=c.getField("name"); //通过反射创建对象/快速创建对象方法 Object obj=c.newInstance(); //赋值 f.set(obj, "张三"); System.out.println(obj); System.out.println(f.get(obj)); }
9.通过反射方式获取成员方法
public Method getMethod(String name, Class<?>... parameterTypes)获取public 修饰的方法
public Method getDeclaredMethod(String name, Class<?>... parameterTypes)获取任意的方法,包含私有的
public Method[] getMethods() 获取本类与父类中所有public 修饰的方法
public Method[] getDeclaredMethods() 获取本类中所有的方法(包含私有的)
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { //获取字节码文件对象 Class c=Class.forName("com.oracle.demo01.Person"); //获取成员方法对象 Method m=c.getMethod("sleep", String.class); //快速创建对象 Object obj=c.newInstance(); m.invoke(obj, "张三"); System.out.println(m); }
10反射配置文件
public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { //创建字符输入流对象,明确数据源 FileReader fr=new FileReader("src/com/oracle/demo02/pro.properties"); //创建Properties集合 Properties pro=new Properties(); //将文件中的键值对读取到集合中 pro.load(fr); //获取类名 String className=pro.getProperty("ClassName"); //获取方法名 String methodName=pro.getProperty("MethodName"); //获取字节码文件对象 Class c=Class.forName(className); //创建成员方法对象 Method m=c.getMethod(methodName); //快速创建对象 Object obj=c.newInstance(); m.invoke(obj); }
浙公网安备 33010602011771号