java反射机制
获取Class对象的三种方式:
1、自定义类对象调用getClass()方法,此方法定义在Object类中。
2、自定义类的class属性(Student.class)。
3、Class类的forName(String)方法,传入完整类名。
实例:
第一种:
Student s = new Student();
Class<? extends Student> class1 = s.getClass();
第二种:
Class class2 = Student.class;
第三种:
Class<?> class3 = Class.forName("com.reflect.Student"); //抛异常ClassNotFoundException
反射机制中的构造方法:
1、通过Class泪的forName(String)方法取得Class类对象。(传入完整类名)
2、通过Class类对象的getDeclaredConstructor()方法获取构造器对象。(传入构造方法参数类型,空参构造不必传入任何参数)
3、设置构造方法的可访问性,setAccessible()方法。(private修饰的构造方法不能直接使用)
4、通过构造器对象调用newInstance()方法创建自定义类对象。(传入参数根据获取的构造器的参数决定)
实例:
// 通过Class类的静态方法获取Class对象
Class<?> c = Class.forName("com.reflect01.Student"); // 抛出ClassNotFoundException
// 通过Class类对象获取构造器对象
Constructor<?> con = c.getDeclaredConstructor(String.class); // 抛出NoSuchMethodException
// 设置private修饰的构造方法可访问
con.setAccessible(true);
// 通过构造器创建类对象
Object obj = con.newInstance("张三"); // 抛出IllegalAccessException,SecurityException,InstantiationException
// 把类对象信息打印到控制台
System.out.println(obj);
反射机制中的成员变量:
1、通过Class类的forName(String)方法获取Class类对象,传入完整类名。
2、通过Class类对象getDeclaredField(String)获取成员属性类对象,传入成员属性名称。
3、设置成员属性的可访问性,setAccessible()。
4、给指定对象的成员属性赋值,set(Object obj , String name)。(给指定对象的成员属性设置值)
实例:
//创建对象
Class<?> c = Class.forName("com.reflect01.Student");
Constructor<?> con = c.getDeclaredConstructor();
con.setAccessible(true);
Object obj = con.newInstance();
System.out.println(obj);
//成员属性需设置给指定对象才有意义
Field field = c.getDeclaredField("name"); //抛出NoSuchFieldException,NullPointerException,SecurityException
//设置成员属性可访问
field.setAccessible(true);
//通过set(Object obj,String name)方法,为指定对象设置获取的成员属性
field.set(obj, "张三");
//把对象信息打印到控制台
System.out.println(obj);
反射机制中的成员方法:
1、通过Class类的forName(String)方法,获取Class类对象。(传入完整类名)
2、通过Class类对象调用getDeclaredMethod(),返回成员方法对象。(传入方法名和参数类型)
3、根据此对象调用invoke(Object obj , ...)方法。(传入对象和方法参数)
实例:
//创建对象
Class<?> c = Class.forName("com.reflect01.Student");
Constructor<?> con = c.getDeclaredConstructor();
con.setAccessible(true);
Object obj = con.newInstance();
//获取成员方法对象
Method m = c.getDeclaredMethod("method3");
//调用invoke()方法(invoke()方法的返回值为该成员方法的返回值
//如果成员方法返回void,则invoke()返回null)
Object inv = m.invoke(obj);
System.out.println(inv);
反射机制的运用实例:
实例一:使用反射机制绕过类型检查(泛型)
//创建集合对象,指定元素类型
ArrayList<String> al = new ArrayList<String>();
al.add("hello");
//获取Class类对象
Class<? extends ArrayList> c = al.getClass();
//获取集合的add方法
Method m = c.getDeclaredMethod("add",Object.class);
//为集合添加元素
m.invoke(al,30);
//把集合元素打印到控制台
System.out.println(al);
实例二:使用反射机制实现对任意类型对象的任意成员属性值进行设置
Class<? extends Object> c = obj.getClass();
Field f = c.getDeclaredField(field);
f.setAccessible(true);
f.set(obj, value);
实例三:属性文件运用到反射机制中
1、在不改变代码的前提下
2、通过配置文件的修改实现不同类的不同方法的调用
//创建属性类对象
Properties prop = new Properties();
//获取输入流
prop.load(new FileInputStream("files/reflect.properties"));
//获取属性文件的键
String className = prop.getProperty("className");
String method = prop.getProperty("methodName");
//根据属性类获取到属性文件的键后,运用到反射机制中
Class c = Class.forName(className);
Constructor con = c.getDeclaredConstructor();
con.setAccessible(true);
Object obj = con.newInstance();
//获取成员方法
Method m = c.getDeclaredMethod(method);
m.setAccessible(true);
//调用成员方法
Object inv = m.invoke(obj);