反射:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
反射:通过字节码文件对象,使用该对象来获取一个类的所有信息。(列如:成员方法、成员变量、构造方法、静态方法、常量、访问权限修饰符、泛型...包括私有)
反射之前做法:
Student s = new Student()
反射之后:
1、获取到学生类对应的字节码文件对象
2、通过字节码文件对象获取构造方法对象
3、通过构造方法对象创建对象
反射的 好处:
1、使得代码的可维护性和扩展性提高
2、反射是框架的核心
如何来获取字节码文件对象?
方式一:
通过Class 类中 getClass()方法,但是此方法的缺点是必须创建对象才能够调用getClass()方法。
方式二:
通过数据类型的class 属性创建,缺点是需要显示声明 XXX类,优点是创建方便。
注:凡是一个方法的 形参希望们转入的是Class类型,推荐使用第二种方式
public void method(Class c) {
}
method(XXX.class);
方式三:
通过Class类中的一个方法Class.forName(类名的全路径)。
优点:不需要显示编写XXX类,满足了开闭原则,提高了代码的可维护性。
public class Student01 { public static void main(String[] args) throws ClassNotFoundException { //方式一:通过get.Class()方法来获取 Student s = new Student(); Class<?> c1 = s.getClass(); System.out.println(c1); //方式二:通过数据类型的属性class类创建来获取 Class<Student> c2 = Student.class; System.err.println(c1 == c2); //方式三;通过Class.forName(类名路径)方法 Class<?> c3 = Class.forName("com.sxt.sext.Student"); System.out.println(c1 == c3); • } }
方式三还可以把路径名直接写到文件,直接在文件里面修改类就可以了,满足了开闭原则,提高了代码的可维护性。如下代码展示
//通过Class.forName(类名路径)方法 Properties pr = new Properties(); pr.load(new FoleReader("com.sxt.sext.Student")); String className = pr.getProperty("className") Class<?> c3 = Class.forName(className); System.out.println(c3); System.out.println(c1 == c3);
Class的作用用于判断一个运行时对象的类型如下:
public static void test1(Object obj){ Class cls = Student.class; if(cls.isInstance(obj)){ • } }
让一个对Student对象可以与String和Integer进行比较如下:
public boolean equals(Object obj){ // 与一个String对象比较 if(String.class.isInstance(obj)){ String other = (String)obj; return other.equals(this.name); }
// 与一个Integer对象比较
if(Integer.class.isInstance(obj)){ Integer other = (Integer)obj; return this.id == other; } return false; }
通过Reflection机制,我们可以直接从class文件反推出它有哪个成员变量、有哪些函数。
遍历Method 已知函数名,找到对象的 Method
Class cls = … String methodName = "setId"; // 获取所有Method列表,顺序比对 Method[] methods = cls.getMethods(); for(Method m : methods){ if(m.getName().equals(methodName)){ break; } }
Class cls = … String methodName = "setId"; Class[] parameterTypes = { int.class }; Method m = cls.getMethod(methodName, parameterTypes);