# java 反射原理
动态代理:
【
如何为 java 对象创建一个代理对象?
java.lang.reflect.Proxy 类:提供了为对象产生代理对象的方法
public static Object newProxyInstance(ClasLoader loader, Class<?>[] interfaces, InvocationHandler h) | |
参数一:用于指定用哪个类加载器,去加载生成的代理类 | |
参数二:指定接口,这些接口用于指定生成的代理长什么,也就是有哪些方法 | |
参数三:用来指定生成的代理对象要干什么事情 |
反射就是能够获取到一个类的全部信息
获取 class 对象:
Class.forName("全类名"); //--------- 全类名: 包名 + 类名 | |
类名.class | |
对象.getclass(); |
三个阶段:
第一个阶段:
使用的是 Class.forName (“全类名”); 获取字节码文件,这是未写入内存
用的是类名.class
用的是对象.getclass ();
获取 class 对象后才能获取构造的方法
/* | |
Class 类中用于获取构造方法的方法 | |
Constructor<?>[] getConstructors () ------ 公共函数的数组 | |
Constructor<?>[] getDeclaredConstructors () ------ 所有函数的数组 | |
Constructor<T> getConstructor (Class<?>... parameterTypes) ----- 返回单个公共构造方法对象 | |
Constructor<T> getDeclaredConstructor (Class<?>... parameterTypes) ----- 返回翻个构造方法的对象 | |
Constructor 类中用于创建对象的方法 | |
T newInstance (odject... initargs) | |
setAccessible (boolean flag) | |
*/ | |
//1. 获取 class 字节码文件对象 | |
Class clazz= Class.forName("MyReflect2.Student"); | |
//2. 获取构造方法 | |
/*Constructor[] cons =clazz.getConstructors(); | |
for (Constructor c:cons){ | |
System.out.println(c); | |
} | |
Constructor[] con1=clazz.getDeclaredConstructors(); | |
for (Constructor c:con1){ | |
System.out.println(c); | |
}*/ | |
// 获取名字 | |
// Constructor con2=clazz.getConstructor(String.class); | |
// System.out.println(con2); | |
// Constructor con3=clazz.getDeclaredConstructor(int.class); | |
// System.out.println(con3); | |
// Constructor con4=clazz.getDeclaredConstructor(String.class,int.class); | |
// System.out.println(con4); | |
Constructor con46=clazz.getDeclaredConstructor(String.class,int.class); | |
// 获取修饰符 | |
int modifiers = con46.getModifiers(); | |
System.out.println(modifiers); | |
// 获取形参列表 | |
Parameter[] parameters= con46.getParameters(); | |
for (Parameter p:parameters) | |
{ | |
System.out.println(p); | |
} | |
// 暴力反射:临时取消权限的校验 | |
// con4.setAccessible(true); | |
// // 创建对象 | |
// Student stu = (Student) con46.newInstance("zhangsan",23); | |
// System.out.println(stu); |
利用反射获取成员变量
package MyReflect3; | |
import java.lang.reflect.Field; | |
public class MyReflectDemo { | |
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException { | |
/* | |
*Class 类中用于获取成员变量的方法 | |
* Field [] getFields (): 返回所有公共成员变量对象的数组 | |
* Field [] getDeclaredFields (): 返回所有成员变量对象的数组 | |
* Field getField (String name): 返回单个公共成员变量对象 | |
* Field getDeclaredField (String name): 返回单个成员变量对象 | |
* | |
* Field 类中用于创建对象的方法 | |
* void set (Object obj ,Object value): 赋值 | |
* Object get (Object obj) 获取值 | |
* | |
*/ | |
//1. 获取 class 字节码文件的对象 | |
Class clazz=Class.forName("MyReflect3.Student"); | |
//2. 获取所有的成员变量 | |
Field[] fields=clazz.getDeclaredFields(); | |
for (Field f:fields){ | |
System.out.println(f); | |
} | |
// 获取单个的成员变量 | |
Field gender = clazz.getDeclaredField("name"); | |
System.out.println(gender); | |
// 获取权限修饰符 | |
int zhuangtai =gender.getModifiers(); | |
System.out.println(zhuangtai); | |
// 获取成员变量的名字 | |
String n = gender.getName(); | |
System.out.println(n); | |
// 获取数据类型 | |
Class type = gender.getType(); | |
System.out.println(type); | |
// 获取成员变量记录的值; | |
Student s = new Student("zhangsan",23,"nan"); | |
gender.setAccessible(true); | |
Object value = gender.get(s); | |
System.out.println(value); | |
// 修改对象里面记录的值 | |
gender.set(s,"lisi"); | |
System.out.println(s); | |
} | |
} |
利用反射获取成员方法:
package MyReflect4; | |
import java.lang.reflect.InvocationTargetException; | |
import java.lang.reflect.Method; | |
public class MyReflectDemo { | |
public static void main(String [] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { | |
/* | |
* Class 类中用于获取成员方法的方法 | |
* Method [] getMethods (): 返回所有公共成员方法对象的数组,包括继承的 | |
* Method0 getDeclaredMethods (): 返回所有成员方法对象的数组,不包括继承的 | |
* Method getMethod (String name,Class<?>.parameterTypes): 返回单个公共成员方法对象 | |
* Method getDeclaredMethod (String name,Class<?>parameterTypes): 返回单个成员方法对象 | |
* Method 类中用于创建对象的方法 | |
* Object invoke (Object obj,,Object..args): 运行方法 | |
* 参数一:用 obj 对象调用该方法 | |
* 参数二:调用方法的传递的参数(如果没有就不写) | |
* 返回值:方法的返回值(如果没有就不写) | |
* | |
* 获取方法的修饰符 | |
* 获取方法的名字 | |
* 获取方法的形参 | |
* 获取方法的返回值 | |
* 获取方法的抛出的异常 | |
* | |
*/ | |
//1. 获取 class 字节码文件对象 | |
Class clazz = Class.forName("MyReflect4.Student"); | |
//2. 获取里面的所有方法对象 (包含符类中所有的父类方法) | |
/*Method[] methods=clazz.getMethods(); | |
for (Method m:methods){ | |
System.out.println(m); | |
}*/ | |
//2,获取里面的所有的方法(不能获取符父类的,可以获取本类中的所有方法) | |
Method[] methods1=clazz.getDeclaredMethods(); | |
for (Method m:methods1){ | |
System.out.println(m); | |
} | |
Method m=clazz.getDeclaredMethod("eat", String.class); | |
m.setAccessible(true); | |
System.out.println(m); | |
// 获取方法的修饰符 | |
int modifiers= m.getModifiers(); | |
System.out.println(modifiers); | |
// 获取方法的名字 | |
String name= m.getName(); | |
System.out.println(name); | |
// 获取方法的形参 | |
Class[] parameterTypes= m.getParameterTypes(); | |
for (Class c:parameterTypes){ | |
System.out.println(c); | |
} | |
// 获取方法的返回值 | |
Class returnType= m.getReturnType(); | |
System.out.println(returnType); | |
// 获取方法的抛出的异常 | |
Class[] exceptionTypes= m.getExceptionTypes(); | |
for (Class e:exceptionTypes){ | |
System.out.println(e); | |
} | |
// 创建对象 | |
Student s=new Student(); | |
Object o=m.invoke(s,"apple");// 参数一 obj 是对象,参数二:调用方法的参数 | |
System.out.println(o); | |
} | |
} |
package MyReflect4; | |
public class Student { | |
private String name; | |
private int age; | |
public Student() { | |
} | |
public Student(String name, int age) { | |
this.name = name; | |
this.age = age; | |
} | |
/** | |
* 获取 | |
* @return name | |
*/ | |
public String getName() { | |
return name; | |
} | |
/** | |
* 设置 | |
* @param name | |
*/ | |
public void setName(String name) { | |
this.name = name; | |
} | |
/** | |
* 获取 | |
* @return age | |
*/ | |
public int getAge() { | |
return age; | |
} | |
/** | |
* 设置 | |
* @param age | |
*/ | |
public void setAge(int age) { | |
this.age = age; | |
} | |
public void sleep(){ | |
System.out.println("睡觉"); | |
} | |
private void eat(String something){ | |
System.out.println("再吃"+something); | |
} | |
private void eat(String something,int age){ | |
System.out.println("再吃"+something); | |
} | |
public String toString() { | |
return "Student{name = " + name + ", age = " + age + "}"; | |
} | |
} |