反射
1、反射的概述
-
java文件在运行时会在方法区中创建一个Class对象
-
Class对象存储在方法区,存储类的所有信息,是类的一面镜子
-
可以通过Class对象获取类的所有信息(私有的都可以),反射在手,天下我有
-
动态加载和静态加载
- 静态加载:发生在编译期
- 动态加载:发生在运行期
-
反射是可以动态获取一个类的所有信息及动态调用类中定义的方法和机制。
2、反射的创建(三种方式)
-
类名.class
-
Class.forName()
-
对象.getClass()
public static void main(String[] args) throws ClassNotFoundException { //1.类名.class Class<Student> clas1 = Student.class;//什么都不加载 System.out.println(clas1);//reflex.Student //2.Class.forName() 需要抛异常 Class clas2 = Class.forName("reflex.Student");//静态代码块加载 System.out.println(clas2);//reflex.Student //3.对象名.getClass() Student s = new Student(); Class clas3 = s.getClass();//reflex.Student //所有加载(静态代码块,非静态代码块,无惨构造) System.out.println(clas3); //4.三种创建方式对象是否相等,相等,方法区中是独一份 System.out.println(clas1 == clas2);//true System.out.println(clas2 == clas3);//true /* 5.三种方式的加载项 类名.class:什么都不加载 Class.forName():静态加载 对象名.getClass():静态非静态初始化 注:整个创建过程只会加载一次,不管创建多少次, 可以想得到Class是独一份是一个对象 */ }
3、常用API
public class TestReflexAPI{
@Test
public void testMethod() throws Exception{
//创建Class对象
Class cla = Student.class;
//getMethods() 获取所以方法(不包括私有)
Method[] mts = cla.getMethods();
System.out.println(Arrays.toString(mts));
//getMethod() 获取单个方法
Method show = cla.getMethod("show", String.class);
System.out.println(show);
//invoke() 执行方法
Student s = new Student();
show.invoke(s, "show....");
/*
getDeclaredMethod() 获取私有方法
getMethod(),不能获取私有属性
NoSuchMethodException 私有方法获取不到
在方法API中获取方法、属性、构造的方法都有一个对呀的Declared方法获取私有的
*/
Method showP = cla.getDeclaredMethod("showP", String.class);
//暴力获取setAccessible()
showP.setAccessible(true);
showP.invoke(s, "showP.....");
}
@Test
public void testFields() throws Exception {
Class cla = Class.forName("reflex.Student");
/*
getFields() 获取全部属性
发现获取属性为空,因为Student类中属性全是私有的
所以只有通过setAccessible暴力获取
*/
Field[] fields = cla.getFields();
System.out.println(Arrays.toString(fields));//[]
//getDeclaredField() 获取私有方法
Field name = cla.getDeclaredField("name");
name.setAccessible(true);
Student s = new Student();
//set() 方法值
name.set(s,"zhang3");
System.out.println(s.getName());//zhang3
}
@Test
public void testConstructors() throws Exception{
Student s = new Student();
//getClass() 获取类
Class cla = s.getClass();
//Class.newIntstance() 返回类的实例
System.out.println(cla.newInstance());
//getConstructors() 获取所有构造方法
Constructor[] cs = cla.getConstructors();
System.out.println(Arrays.toString(cs));
/*
Cnostructor.newInstance()
给指定构造方法给一个指定实例,并返回一个Object对象
*/
Student s1 = (Student) cs[1].newInstance( "zhang3", "男", 18);
System.out.println(s1);//Student{name='zhang3', sex='男', age=18}
}
}