java反射机制是在运行状态中,对于任意一个类。 都能够知道这个类的属性和方法, 对于任意一个对象,都能够调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
在java类中如何操作反射:
Class类是一切反射的根源,
Class 与 class 的区别
class是java的关键字,是在声明java类的时候用的
Class是java JDK提供的一个类, 完整路径为java.Lang.Class
class类只用于类的声明
Class :用于抽象类的相关信息, java是面向对象的一般一些事物抽象成一个类,如将学生信息抽象成Student这个类,Student会抽象学生的属性,java中也把java类抽象为一个类叫做Class,其抽象可java类的包名,方法等信息。
Class类的对象就是一个类(字节码)文件,即可以直接在JVM中运行的
得到Class对象的三中方法
1:Object类的getClass()方法。
2:.class 形式访问
3:通过Class的forName ()方法。
为了演示效果首先创建一个person类(含 name ,age, sex), 提供空,及非空构造方法 ,set与get方法以及toString方法。
测试如下代码:
Person p1 = new Person(20, "小白", 'M');
Person p2 = new Person(22, "JAMES", 'M');
// 创建Clas方法的方式一, 一个Class对象代表一个字节码
Class cla1 = p1.getClass();
Class cla2 = p2.getClass();
System.out.println(cla1==cla2);
/*输出结果为true
*/
//第二种方式
Class cla3 = Person.class;
System.out.println(cla3==cla2);
// 第三种方式
Class cla4 =Class.forName("com.xiyou.reflection.Person");
System.out.println(cla4 ==cla1);
输出结果均为true, 这是因为Person类对应的class 文件,通过类加载器,加载到内存中,这个类会加载一次, 在内存中存取该类的字节码文件就会有一份,是以Class类型存储的,相当于存储了一个Class类的对象, 不管实例化多少次,引用的都是内存中的同一个对象的实例。
通过类信息实例化对象
通过调用无参构造方法newInstance ()创建此Class对象所表示的一个新实例
Person p3 = (Person)cla1.newInstance(); //调用Person的无参构造方法(如果类中没有无参构造方法会发生错误)
System.out.println(p3);
Constructor 提供关于类的单个构造方法的信息以及对它的访问权限
Constructor [] cs = cla2 .getConstructors(); //获取当前类的所有构造方法
Constructor c1 = cla3.getConstructor( int.class, String.class,char.class);
Person p4= (Person) c1.newInstance(20, "KOBE",'W');
System.out.println(p4.toString());
可以通过反射机制获取,类中的所有的方法,以及私有放法的属性
通过getMethods();可以获取所有的公共方法,但是不包括私有方法
可以使用Method [] d =cla2.getDeclaredMethods(); 获取所有的方法,但是不包括私有方法
获取属性的信息:
Field[] fs= cla3 .getFields(); //获取共有属性
也可以获取私有属性
Field [] fs2 = cla3.getDeclaredFields(); //获取私有属性
也可以调用方法和属性实现方法的使用
Method method= cla3.getMethod("setName",String.class);
// 调用方法
method.invoke(p2, "UAHUA");//相当于p4.setName ("huahua");
最强大的功能是可以调用私有方法和属性
Method ds = cla3.getDeclaredMethod("say" );
ds.setAccessible(true);//忽略检查访问修饰符
// invoke (Object object, Object... args) :调用类中的方法,传入实例化对象,以及具体参数的内容
ds.invoke(p2);
调用属性并且使用
Field fd =cla2.getDeclaredField("age");
fd.setAccessible(true);
System.out.println(fd.get(p2));// 获取p2age属性值
fd.setInt(p2, 6); //给p2对象的age赋值为6