反射是什么(反射是框架设计的灵魂)
Java的反射机制是指在程序运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。
反射使用的场景
框架中大量使用了动态代理,而动态代理的实现也依赖反射
Java的注解
优缺点
优点:让代码更加灵活、为各种框架开箱即用的功能提供了便利、让我们在运行时有了分析类的能力
缺点:增加了安全问题,比如可以无视泛型参数的安全检查(泛型参数的安全检查发生在编译时)。另外。反射的性能也要稍微差点,不过,对于框架来说是影响不大的。
反射提供的功能
1、在运行时判断任意一个对象所属的类
2、在运行时构造任意一个类的对象
3、在运行时判断任意一个类所具有的成员变量和方法
4、在运行时调用任意一个对象的方法
获取反射入口(Class对象)的三种方法
1.通过 Class.forName("全类名")
//1.Class.forName("全类名")
Class cls1 = Class.forName("domain.Person");
2.通过 类名.class
//2.类名.class
Class cls2 = Person.class;
3.通过 对象.getClass()
//3.对象的getClass()
Person p = new Person();
Class cls3 = p.getClass();
根据反射入口(Class对象)获取类的各种信息
获取类的成员变量
//0.获取Person的Class对象
Class personClass = Person.class;
//1.获取成员变量
Field[] fields = personClass.getFields();//获取所有public修饰的成员变量
for (Field field : fields){
System.out.println(field);
}
System.out.println("=========");
Field a = personClass.getField("a");//获取指定public修饰的成员变量
//获取成员变量a的值
Person p = new Person();
Object value = a.get(p);
System.out.println(value);//null
//设置a的值
a.set(p,"张三");
System.out.println(p);
System.out.println("======");
//Field[] getDeclaredFields()
Field[] declaredFields = personClass.getDeclaredFields();//获取所有的成员变量,不考虑修饰符
for (Field declaredField : declaredFields){
System.out.println(declaredField);
}
Field d = personClass.getDeclaredField("d");
//忽略访问权限修饰符的安全检查
d.setAccessible(true);//暴力反射
Object value2 = d.get(p);
System.out.println(value2);//null
//通过Class对象来类的实例
Person person = (Person) cls1.newInstance();
System.out.println(person);
获取类的构造方法
//0.获取Person的Class对象
Class personClass = Person.class;
Constructor constructor = personClass.getConstructor(String.class, int.class);
System.out.println(constructor);
//创建对象
Object person = constructor.newInstance("zhangsan",18);
System.out.println(person);
System.out.println("=========");
Constructor constructor1 = personClass.getConstructor();
System.out.println(constructor);
//创建对象
Object person1 = constructor1.newInstance();
System.out.println(person);
获取类的方法
//0.获取Person的Class对象
Class personClass = Person.class;
Method eat_method = personClass.getMethod("eat");
Person p = new Person();
//执行方法
eat_method.invoke(p);
Method eat_method2 = personClass.getMethod("eat", String.class);
//执行方法
eat_method2.invoke(p,"饭");
System.out.println("=======");
//获取所有public修饰的方法
Method[] methods = personClass.getMethods();
for (Method method : methods){
System.out.println(method);
System.out.println(method.getName());
}
System.out.println(methods.length);
//类名
String className = personClass.getName();
System.out.println(className);//domain.Person