反射机制概述和代码举例
1.反射的概述
1.被视为动态语言的关键,反射机制允许程序在运行期间,借助于反射相关的api取得任何
类内部信息,直接操作任何的属性和方法
2.不使用反射需要考虑封装性,出了类之后不能调用私有属性 使用之后打破封装性
场景:
1.从程序员开发者的角度讲,开发中主要完成业务代码,对对象方法的味道都是确定的,
使用很多
2.主要体现了动态性,运行时动态获取对象所属的类,动态的调用方法,
所以在设计框架的时候会大量使用反射
3.单例模式饿汉和懒汉中私有化构造器,单例模式也可以调用(暴力反射)
注意:
1. 他和封装性并不冲突没有冲突和bug封装性体现的是,是否建议调用内部api的问题,
private意味着不建议调用
2/ 反射体现的是我们能否调用的问题,因为我们类的完整结构都加载到了内存中,
所以我们有能力调用
代码:
先写一个有public修饰和private修饰的people类
public class People {
public String name;
private int age;
@Override
public String toString() {
return "People{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public People() {
}
private People(int age) {
System.out.println("People constructor");
}
public void show(){
System.out.println("Name: " + name);
}
private void sayHello(){
System.out.println("Hello, " + name);
}
}
下面是用反射实现的获取方法属性和构造方法
public void test()throws Exception{
//使用反射
Class clazz = People.class;
People person = (People) clazz.newInstance();
System.out.println(person);
//调用属性
Field name = clazz.getField("name");
name.set(person,"hh");
System.out.println(name.get(person));
//调用方法
Method showMethod = clazz.getMethod("show");
showMethod.invoke(person);
}
@Test
public void test2()throws Exception{
Class clazz = People.class;
Constructor declaredConstructor = clazz.getDeclaredConstructor(int.class);
declaredConstructor.setAccessible(true);
People person = (People) declaredConstructor.newInstance(13);
//2调用私有属性
Field declaredField = clazz.getDeclaredField("age");
declaredField.setAccessible(true);
declaredField.set(person,11);
//3.调用私有方法
Method declaredMethod = clazz.getDeclaredMethod("sayHello");
declaredMethod.setAccessible(true);
declaredMethod.invoke(person);
}
}