反射机制
反射是java中的动态机制,它允许我们在程序运行期间再确定类的实例化,方法的调用,属性的调用等,而不是传统意义上的在编码期间确定。因此,反射可以大大的提高代码的灵活度,但是随之而来的是更多的系统开销和较慢的运行速度,因此不能过度的依赖反射。
class类
Class的每一个实例用于表示JVM加载的一个类,所以我们也称Class的实例 为类的类对象。 当JVM加载一个类时会同时实例化一个Class的实例与之对应,这个Class实例 中会保存该类的一切信息(类名,有哪些方法,构造器,属性,注解等等) 我们在程序运行期间通过某个类的类对象来操作这个类。因此使用反射操作某个 类的第一件事就是获取该类的类对象
获取一个类的类对象有三种方式:
- 类名.class 例如: Class cls = String.class; Class cls = int.class (基本类型只能通过这种方式获取类对象)
- Class.forName(String className) 通过Class的静态方法forName,传入对应类的完全限定名(包名.类名)的 形式获取类对象 Class cls = Class.forName("java.lang.String");
- 通过类加载器ClassLoader加载类对象
使用反射机制进行对象的实例化
Class提供的方法
- Object newInstance():该方法可以使用其表示的类的无参构造器进行对象实例化
使用有参构造器实例化对象
- 加载类对象
- 获取指定的构造器:Person(String name,int age)
使用反射机制调用方法
- 调用无参数方法
- 通过类对象获取要调用的方法
- 通过方法对象执行该方法
- 调用有参方法
public class ReflectDemo5 { public static void main(String[] args) throws Exception { Class cls = Class.forName("reflect.Person"); Object o = cls.newInstance(); //say(String info) Method m = cls.getMethod("say",String.class); m.invoke(o,"hello~~");//p.say("hello~~") //say(String info,int sum) Method m2 = cls.getMethod("say",String.class,int.class); m2.invoke(o,"嘿嘿",5); } }
- 访问私有方法
public class ReflectDemo6 { public static void main(String[] args) throws Exception { Person p = new Person(); // p.hehe();//编译不通过! Class cls = Class.forName("reflect.Person"); Object o = cls.newInstance(); //获取私有方法:private void hehe() // Method m = cls.getMethod("hehe"); //获取私有方法不能用getMethod,(这用来获取公开方法) Method m = cls.getDeclaredMethod("hehe"); m.setAccessible(true);//强制访问 m.invoke(o);//o.hehe() } }
- 调用无参数方法