java 反射
反射十分强大,可以调用知道任何类,方法,属性,反射是框架的灵魂
1.要反射当然要先找到入口有3种方法获得入口
对象.getclass()
Parson ps=new Parson();
Class<?> cl= ps.getClass();
Class.forName("包名.类名")
Class<?> forName = Class.forName(“Reflect.parson”);
类名class
Class<?> clazz= parson.class;
有了这3种方法,就可以体验反射的强大了
2.反射可以干嘛
1获取公共方法 getMethods()&获取当前类的所有方法getDeclaredMethods() ★
公共方法:获取公共的方法(本类,父类,接口,符合访问修饰符的类)
当前类的所有方法:只能的当前类,忽略修饰符(private也可以访问)
private static void demo2() throws ClassNotFoundException {
//先获取入口
Class<?> forName = Class.forName("Reflect.parson");
//获取公共方法
Method[] methods = forName.getMethods();
for (Method method : methods) {
System.out.println(method);
}
System.out.println("===================");
//获取当前类的所有方法(1,只能的当前类,忽略修饰符(private也可以访问))
Method[] declaredMethods = forName.getDeclaredMethods();
for (Method method : declaredMethods) {
System.out.println(method);
}
2,获取接口 getInterfaces() ★
private static void demo3() throws ClassNotFoundException {
Class<?> forName = Class.forName("Reflect.parson");
Class<?>[] interfaces = forName.getInterfaces();
for (Class<?> class1 : interfaces) {
System.out.println(class1);
}
}
3,获取 父类 getSuperclass()
private static void demo4() throws ClassNotFoundException {
Class<?> forName=Class.forName("Reflect.parson");
Class<?> superclass = forName.getSuperclass();
System.out.println(superclass);
}
4,获取构造方法 getConstructors() ★
private static void demo5() throws ClassNotFoundException {
Class<?> forName = Class.forName("Reflect.parson");
Constructor<?>[] constructors = forName.getConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println(constructor);
}
}
5获取属性 getFields() ★
private static void demo6() throws ClassNotFoundException {
Class<?> forName = Class.forName("Reflect.parson");
Field[] fields = forName.getFields();
for (Field field : fields) {
System.out.println(field);
}
}
6获取当前反射所代表类(接口) 的对象(实例) newInstance( ★
private static void demo7() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Class<?> forName = Class.forName("Reflect.parson");
Object newInstance = forName.newInstance();
parson ps=(parson)newInstance;
ps.InterfaceMethod();//获取parson 的实例,调用方法
}
3反射的具体使用
获取对象实例,并操作对象,操作方法
// 获取对象实例,并操作对象
Class<?> forName = Class.forName("Reflect.parson");
// 1获取对象
parson parson = (parson) forName.newInstance();
parson.setName("weng");
System.out.println(parson.getName());
System.out.println("============================");
// 操作属性
// Field field = forName.getField("id");//不能访问私有的,只能的公共的
Field field = forName.getDeclaredField("id");
// 开启权限
// 修改属性的访问权限 使用反射时,如果 因为访问修饰符限制造成异常,
// 可以通过 Field/Method/Constructor.setAccessible(true)
field.setAccessible(true);//
field.set(parson, 1);
System.out.println(parson.getId());
System.out.println("==============================");
// 操作方法
Method method = forName.getDeclaredMethod("InterfaceMethod", null);
method.invoke(parson, null);// 方法的调用:invoke()
System.out.println("=============");
// 有参数类型的
Method method2 = forName.getDeclaredMethod("testname", String.class);
method2.setAccessible(true);
method2.invoke(parson, "weng");
System.out.println("=================");
// 操作构造方法
// 获取指定的构造方法
// 在反射中,根据类型 获取方法时:基本类型(int、char...)和包装类(Integer,Character)是不同的类型
Constructor<?> constructor1 = forName.getConstructor(null);
System.out.println(constructor1);
Constructor<?> constructor2 = forName.getDeclaredConstructor(int.class);
System.out.println(constructor2);
// 根据获取的private构造方法,获取对象实例
parson instance2 = (parson) constructor2.newInstance(1);
System.out.println(instance2);
parson par = (parson) constructor1.newInstance();
System.out.println(par);
动态加载 类名 和方法
1,先创建prop.txt 文件
classname=Reflect.parson//类名
methodname=InterfaceMethod//方法名
2,进行操作
public static void demo2() throws FileNotFoundException, IOException, ClassNotFoundException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException,
NoSuchMethodException, SecurityException {
Properties prop = new Properties();
// 加载属性文件
prop.load(new FileReader("prop.txt"));
// 读取属性
String classname = prop.getProperty("classname");
String methodname = prop.getProperty("methodname");
Class<?> forName = Class.forName(classname);//反射入口
Method method = forName.getMethod(methodname);//获取方法
Object instance = forName.newInstance();//创建实例
method.invoke(instance);//调用实例
}
反射可以越过泛型的检查
public static void demo3() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
List<Integer> list=new ArrayList<Integer>();
list.add(123);
list.add(2);
Class<?> rf= list.getClass();
Method method = rf.getMethod("add",Object.class);//修改方法参数类型为Object
method.invoke(list, "weng");
System.out.println(list);
}
万能的set方法
1,创建PropertyUtil
/**
*
* @param obj //对象
* @param propertyName //set属性
* @param value //设置值
* @throws SecurityException
* @throws NoSuchFieldException
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
public static void setPropertys(Object obj,String propertyName,Object value) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException{
Class<?> clazz=obj.getClass();
Field field = clazz.getDeclaredField(propertyName);
field.setAccessible(true);
field.set(obj, value);
}
public static void demo4() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
Student student=new Student();
PropertyUtil.setPropertys(student, "name", "weng");
System.out.println(student.getName());
}
4小结
访问私有的方法使用 getDeclared***();
修改属性的访问权限 使用反射时,如果 因为访问修饰符限制造成异常,
可以通过 Field/Method/Constructor.setAccessible(true)
field.setAccessible(true);