Day18 (二)反射
反射机制是什么
反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
反射机制能做什么
反射机制主要提供了以下功能:
-
在运行时判断任意一个对象所属的类;
-
在运行时构造任意一个类的对象;
-
在运行时判断任意一个类所具有的成员变量和方法;
-
在运行时调用任意一个对象的方法;
-
生成动态代理。
反射机制的优点与缺点
为什么要用反射机制?直接创建对象不就可以了吗,这就涉及到了动态与静态的概念,
静态编译:在编译时确定类型,绑定对象,即通过。
动态编译:运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多
态的应用,有以降低类之间的藕合性。
一句话,反射机制的优点就是可以实现动态创建对象和编译,体现出很大的灵活性,特别是在J2EE的开发中
它的灵活性就表现的十分明显。比如,一个大型的软件,不可能一次就把把它设计的很完美,当这个程序编
译后,发布了,当发现需要更新某些功能时,我们不可能要用户把以前的卸载,再重新安装新的版本,假如
这样的话,这个软件肯定是没有多少人用的。采用静态的话,需要把整个程序重新编译一次才可以实现功能
的更新,而采用反射机制的话,它就可以不用卸载,只需要在运行时才动态的创建和编译,就可以实现该功
能。
它的缺点是对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它
满足我们的要求。这类操作总是慢于只直接执行相同的操作。
反射的应用
package day18; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; class Student{ private int no; public String name; public Student() { System.out.println("无参构造"); } public Student(int no, String name) { this.no = no; this.name = name; System.out.println("带参构造:"+no+","+name); } public void f1() { System.out.println("无参无返回值得方法f1"); } public String f2(String s,int n) { return "串"+s+":"+n; } } public class TestClass1 { public static void main(String[] args) throws Exception { // Class反射 //运行 期 获得类中的信息 //先获得 字节码文件的对象 Class<?> c = Class.forName("day18.Student"); // Class<Student> c = Student.class; // Class<? extends Student> c = new Student().getClass(); //属性---------------------------------------------------------- System.out.println("-------------------属性 ----------------------"); // Field [] fs = c.getFields();//public Field [] fs = c.getDeclaredFields();//所有属性 for(Field f: fs) { System.out.println(f.getName()); System.out.println(f.getType()); System.out.println(Modifier.toString(f.getModifiers())); } Field f1 = c.getDeclaredField("name"); Object obj = c.newInstance();//调用构造 f1.set(obj, "Tom"); System.out.println(f1.get(obj)); Field f2 = c.getDeclaredField("no"); f2.setAccessible(true);//设置允许访问权限 f2.set(obj, 11); System.out.println(f2.get(obj)); //方法---------------------------------------------------------------- System.out.println("------------------方法--------------------------"); Method [] ms = c.getDeclaredMethods(); for(Method m :ms) { System.out.println(m.getName()); System.out.println(m.getReturnType()); System.out.println(Arrays.toString(m.getParameterTypes())); } Method m1 = c.getDeclaredMethod("f1"); m1.invoke(obj); Method m2 = c.getDeclaredMethod("f2", String.class,int.class); System.out.println(m2.invoke(obj, "hello",123)); //构造-------------------------------------------------------------- System.out.println("-------------------构造--------------------------------"); Constructor<?> [] crs = c.getDeclaredConstructors(); for(Constructor cr :crs) { System.out.println(cr.getName()); System.out.println(Arrays.toString(cr.getParameterTypes())); } Constructor cr1 = c.getDeclaredConstructor(); cr1.newInstance(); Constructor cr2 = c.getDeclaredConstructor(int.class,String.class); cr2.newInstance(111,"郭靖"); } }