Java反射
反射
什么是反射?
用官方语言回答就是: 反射java语言中的一种机制,通过这种机制可以动态的实例化对象、读写属性、调用方法
一切反射相关的代码都从获得类对象开始
1 对象.getClass()
2 Class.forName(完整类名)
3 类名.class
它们得到结果都是一样的,反射到的类实例
反射的三大多用
1 实例化对象
2 动态调用方法
3 读写属性
1.实例化对象 .newInstance()
getConstructor 与 getDeclaredConstructor的区别在于
getConstructor获取public修饰的
getDeclaredConstructor 获取的所有的构造器 不管是私有化的还是公开的…都是可以获取到 ! 如果是在有参数的情况下,一定要用 getDeclaredConstructor
public static void main(String[] args) throws Exception {
Class<Student> clz = Student.class;//如果直接用类对象去点newInstance,那么默认就只能调用无参构造函数来实例化
// 通过反射的方式调用无惨构造器来实例化对象
// Student stu = (Student)clz.newInstance();
// 通过反射的方式调用一个参数的构造器来实例化对象 Class
// Constructor c = clz.getConstructor(String.class);
// Student stu = (Student) c.newInstance("s001");
// 通过反射的方式调用两个参数的构造器来实例化对象 Class
// Constructor c = clz.getConstructor(String.class,String.class);
// Student stu = (Student) c.newInstance("s001","zs");
// 通过反射的方式调用私有的构造器来实例化对象 Class
Constructor c = clz.getDeclaredConstructor(Integer.class);
c.setAccessible(true);
Student stu = (Student) c.newInstance(23);
}
2 动态调用方法
Method m;
m.invoke
获得私有的构造方法必须要用到这个 field.setAccessible(true);
public static void main(String[] args) throws Exception{
Class clz = Student.class;//如果直接用类对象去点newInstance,那么默认就只能调用无参构造函数来实例化
// Method m = clz.getDeclaredMethod("hello");
//第一个参数指的是,类类的类实例的类实例
// 第二个参数,指的是调用方法所携带的可变参数
// Method类invoke方法的返回值就是被调用的方法的返回值
// 如果被调用的方法的不具备返回值,那么返回null
// System.out.println(m.invoke(clz.newInstance()));
// Method m = clz.getDeclaredMethod("hello", String.class);
// m.invoke(clz.newInstance(), "xxx");
Method m = clz.getDeclaredMethod("add",Integer.class,Integer.class);
m.setAccessible(true);
Object invoke = m.invoke(clz.newInstance(), 20,5);
System.out.println(invoke);
}
在这里调用了add方法 所以20+5结果等于25
3 读写属性
Field set/get
Field[] : 获得类所有属性
Field : 获取类指定属性
public static void main(String[] args) throws Exception{
Student stu = new Student("s001","zs");
stu.age = 22;
Class clz = stu.getClass();
//获得类所有属性
// Field[] fields = clz.getDeclaredFields();
// for (Field field : fields) {
// field.setAccessible(true);
// System.out.println(field.getName()+":"+field.get(stu));
// }
// 共有的 获取类指定属性
// Field field = clz.getDeclaredField("age");
// field.set(stu, 45);设置属性值
// System.out.println(stu.age);
Field field = clz.getDeclaredField("sname");
field.setAccessible(true);
field.set(stu, "ls");
System.out.println(stu.getSname());
}
访问修饰符
getModifiers()
PUBLIC: 1 (二进制 0000 0001)
PRIVATE: 2 (二进制 0000 0010)
PROTECTED: 4 (二进制 0000 0100)
STATIC: 8 (二进制 0000 1000)
FINAL: 16 (二进制 0001 0000)
SYNCHRONIZED: 32 (二进制 0010 0000)
VOLATILE: 64 (二进制 0100 0000)
TRANSIENT: 128 (二进制 1000 0000)
NATIVE: 256 (二进制 0001 0000 0000)
INTERFACE: 512 (二进制 0010 0000 0000)
ABSTRACT: 1024 (二进制 0100 0000 0000)
STRICT: 2048 (二进制 1000 0000 0000)
int java.lang.reflect.Field.getModifiers()
以整数形式返回此 Method 对象所表示方法的 Java 语言修饰符
boolean java.lang.reflect.Modifier.isPublic(int mod)
如果整数参数包括 public 修饰符,则返回 true,否则返回 false。其他方法类似
方法的修饰符获取与属性类似
详细可参考:http://blog.csdn.net/xiao__gui/article/details/8141216
上一篇: Cglib动态代理反编译生成类
下一篇: CGLIB动态代理使用与原理详解