java反射之初认识

来源:互联网 发布:mac卸载软件后的垃圾 编辑:程序博客网 时间:2024/06/05 00:17

1、java反射机制的概念?

java反射机制是指java在运行状态时,可以知道任意一个类的属性和方法,对于任意一个对象,可以调用它的所有属性和方法,这种动态获取信息,以及动态获取对象方法的功能称之为java反射机制

2、获得类定义信息的几种方式?

Test test = new Test();
1)Class cla = test.getClass();
2)Class cla = Test.class;
3)Class cla = Class.forName("类的路径全名");//注意这种方式一定要包名,加上类名,名字不全的话,会报类找不到的异常
4)Class cla = ClassLoader.getSystemClassLoader().loadClass("类的路径全名");

3、在获取Class对象之后,一般会去获取下面几种对象:Constructor对象、Field对象、Method对象

1)获取Constructor对象

Constructor[] constructors = cla.getDeclaredConstructors();
获取当前class的所有的构造方法
Constructor[] constructors = cla.getConstructors();
获取当前class的所有的public的构造方法
Constructor constructor = cla.getConstructor(int.class);
获取当前class的int入参的公有的构造方法
Constructor constructor = cla.getDeclaredConstructor(String.class);
获取当前class的String入参的构造方法(不限制权限修饰符)

Constructor对象的常见用途
程序中经常会遇到先获取constructor构造方法,然后通过constructor.newInstance()方法来获取对象的方式:
Constructor<TestForReflect> constructor = cla.getConstructor(int.class);//入参与构造函数一致
TestForReflect instance = constructor.newInstance(3);

注意:
1、如果获取的Class对象是私有的,那么,需要加上这行代码:constructor.setAccessible(true);
不然constructor.newInstance(aobj)方法会报错:
Class test.Test can not access a member of class test.TestForReflect with modifiers "private"

2、Class也是可以用newInstance()方法的,但是方法入参不可以传参数
例如:
Class cla = Class.forName("test.TestForReflect");
TestForReflect testForReflect = (TestForReflect) cla.newInstance();

2)获取Field对象
getField(String name)
获取当前Class的修饰符为public属性字段名是name的Field对象,例如:cla.getField("b")
getDeclaredField(String name) 
获取当前Class的属性字段名是name的Field对象,不限制修饰符,例如:cla.getDeclaredField("b")
getFields() 
获取当前Class的修饰符为public属性字段Field对象数组
getDeclaredFields()
获取当前Class的属性字段Field对象数组(不限制修饰符)

Field对象的常见用途
get(Object obj) :获取该Field对象的值
set(Object obj, Object value) :给该Field对象设置值
例如:
TestForReflect testForReflect = new TestForReflect(5);
Class cla = testForReflect.getClass();
Field field = cla.getField("c");
System.out.println(field.get(testForReflect));//取出testForReflect对象中成员变量名为c的值
field.set(testForReflect, 7);//改变这个值
System.out.println(testForReflect.c);

注意:如果是私有变量,对于Field对象操作的时候要加这段代码:field.setAccessible(true);不然是操作不了类的私有属性的

3)获取获取Method对象
getMethod(String name, Class<?>... parameterTypes)
获取名字为name的公共public方法,前面一个参数是方法名字,后面是方法的入参类型类,例如:Method method = cla.getMethod("cc", String.class);
getDeclaredMethod(String name, Class<?>... parameterTypes) 
获取名字为name的方法,前面一个参数是方法名字,后面是方法的入参类型类,例如:Method method = cla.getDeclaredMethod("aa", int.class);
getMethods()
获取公共public方法数组Method[]
getDeclaredMethods()
获取方法数组Method[]

常见的使用方式:
Method method = cla.getDeclaredMethod("aa", int.class);//获取方法,第一个参数是方法名称,后面是方法入参的参数类型类
method.setAccessible(true);//私有方法需要设置,才能调用
method.invoke(testForReflect, 1994);//方法调用,第一个入参是方法所在类的对象,后面的参数是方法的入参


4、总结

对于已知的一个对象或则一个类,要想在运行期间操作类中的字段或者方法,必须先获取Class类型类对象,然后通过这个Class对象,去获取Field对象和Method对象,如果想操作构造函数,则获取Constructor对象。
通过反射得到的field对象,Method对象,或则Constructor对象,如果不加setAccessible()这个方法,也是无法访问私有成员的。