Java的反射机制是Java特性之一,反射机制是构建框架技术的基础所在。Java反射机制是指在运行状态中,动态获取信息以及动态调用对象方法的功能。
Java反射有3个动态性质:运行时生成对象实例,运行时调用方法,运行时更改属性。
一、Java反射常用API
使用java反射技术常用的类如下:
Class类:反射的核心类,反射所有的操作都是围绕该类来生成的。通过Class类,可以获取类的属性、方法等内容信息。
Field类:表示类的属性,可以获取设置类中属性的值。
Method类:表示类的方法,可以获取类中方法的信息,或者执行方法。
Constructor类:表示类的构造方法。
二、反射的应用
1、获取类的信息
(1)获取Class对象,常用的有3种方法
①调用对象的getClass()方法
Student s =new Student();//Student为自定义的学生类型 Class c=s.getClass();
②调用类的class属性
Class c=Student.class;//Student为自定义的学生类型
③使用Class类的forName()静态方法。该方法需要传入某个类的全名的字符串,即要在类名前添加完整的包名
Class c=Class.forName("com.pb.jadv.Student");//正确 Class c=Class.forName(Student);//错误
(2)从Class对象获取信息
Class<Student> sc=Student.class;//使用类型.class
①访问Class对应的类所包含的构造方法
获取构造方法 //获取公共的构造方法 Constructor<Student> c = sc.getConstructor(int.class,double.class); //获取所有的 Constructor<Student> c = sc.getDeclaredConstructor(int.class,double.class,String.class);
②访问Class对应的类所包含的方法
//访问公共的方法 Method method = sc.getMethods(方法名,参数类型); //访问所有的方法 Method method = sc.getDeclaredMethod(方法名,参数类型);
③访问Class对应的类所包含的属性
Field[] getFields():返回此Class对象所包含的类的public属性
Field[] getDeclaredFields():返回此Class对象所包含的类的全部属性
2、创建对象
通过反射来创建对象有如下两种方式。
①使用Class对象的newInstance()方法创建对象
使用Class对象的newInstance()方法来创建该Class对象对应类的实例,要求该Class对象的对应类有默认构造方法,而执行newInstance()方法时实际上是利用默认构造方法来创建该类的实例。
②使用Constructor对象创建对象
指定构造方法创建Java对象需要如下3个步骤:
获取该类的Class对象
利用Class对象的getConstructor()方法来获取指定构造方法
调用Constructo的newInstance()创建对象
3、访问类的属性
//使用对象强行对属性赋值 Field stuNo = sc.getDeclaredField("stuNo"); stuNo.setAccessible(true);//获取对私有属性取值和赋值的权限 stuNo.set(s,18);
4、访问类的方法
//使用对象调用方法 Method method = sc.getDeclaredMethod("getStuNo");//根据方法名获取方法 method.setAccessible(true);//强行获取权限 Object o = method.invoke(s);//执行对象方法
5、获取父类
Class<? super Student> suc = sc.getSuperclass();//获取父类的Class对象 Constructor<? super Student> cs = suc.getConstructor();//获取父类默认的构造方法 Object object = cs.newInstance(); System.out.println(object);
6、获取接口
Class<?>[] i = sc.getInterfaces(); Class<?> inter = i[0];//获取父接口
具体实例
public interface Talkable { }
public class Human { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public void think(){ System.out.println("胡思乱想"); } }
public class Student extends Human implements Talkable{ public int stuNo; private double score; // private Student() { // } public Student(int stuNo, double score) { this.stuNo = stuNo; this.score = score; } private Student(int stuNo, double score,String name) { this.stuNo = stuNo; this.score = score; setName(name); } private int getStuNo() { return stuNo; } private void setStuNo(int stuNo) { this.stuNo = stuNo; } public double getScore() { return score; } public void setScore(double score) { this.score = score; } @Override public String toString() { return "Student{" + "stuNo=" + stuNo + ", score=" + score + '}'+getName(); } }
public class TestReflect<T> { public static void main(String[] args) throws Exception { //1、获取类型Class Class<Student> sc=Student.class;//使用类型.class // Student s=new Student();//由于s的类型不能确定具体的对象地址(可能是子类类型) // Class<?extends Student>sc1=s.getClass();//使用对象.class // Class<?>sc2=Class.forName("cn.kgc.Student"); //2、获取构造方法并创建对象 // Constructor<Student> c = sc.getConstructor(int.class,double.class);//获取公共的构造方法 Constructor<Student> c = sc.getDeclaredConstructor(int.class,double.class,String.class);//获取所有的 c.setAccessible(true); Student s=c.newInstance(3,88,"aa");//通过构造方法创建对象 System.out.println(s); // System.out.println(s.getScore()); System.out.println(s.getName()); //3、使用对象调用方法 // Method method = sc.getDeclaredMethod("getStuNo");//根据方法名获取方法 Method method = sc.getDeclaredMethod("setStuNo", int.class); method.setAccessible(true);//强行获取权限 // Object o = method.invoke(s);//执行对象方法 method.invoke(s,15); // System.out.println(o); System.out.println(s); //4、使用对象强行对属性赋值 Field stuNo = sc.getDeclaredField("stuNo"); stuNo.setAccessible(true); stuNo.set(s,18); System.out.println(s); //5、获取父类 Class<? super Student> suc = sc.getSuperclass();//获取父类的Class对象 Constructor<? super Student> cs = suc.getConstructor();//获取父类默认的构造方法 Object object = cs.newInstance(); System.out.println(object); Method think = suc.getMethod("think"); think.invoke(object); //6、获取接口 Class<?>[] i = sc.getInterfaces(); Class<?> inter = i[0];//获取父接口 } }