反射

反射

获取Class的实例的四种方式

//获取Class的实例的四种方式
@Test
public void test1() throws Exception{
   //方式一:调用运行时类的属性:.class
   Class clazz1 = Person.class;
   System.out.println(clazz1);

   //方式二:通过运行时类的对象,调用getClass()
   Person p1 = new Person();
   Class clazz2 = p1.getClass();
   System.out.println(clazz2);

   //方式三:调用Class的静态方法:forName(String classPath)
   Class clazz3 = Class.forName("com.reflection.java.Person");
   System.out.println(clazz3);

   //方式四:使用类的加载器:ClassLoader(了解)
   ClassLoader loader = ReflectionTest.class.getClassLoader();
   Class clazz4 = loader.loadClass("com.reflection.java.Person");
   System.out.println(clazz4);

   System.out.println(clazz1 == clazz2);
   System.out.println(clazz1 == clazz3);
   System.out.println(clazz1 == clazz4);

}

关于java.lang.Class类的理解

  1. 类的加载过程: 程序经过javac.exe命令以后,会生成一个或多个字节码文件(.class结尾),接着我们使用java.exe命令对某个字节码文件进行解释运行。相当于将某个字节码文件加载到内存中。此过程就称为类的加载。加载到内存中的类,我们就称为运行时类,此 运行时类,就作为Class的一个实例。换句话说,Class的实例就对应着一个运行时类。

  2. 加载到内存中的运行时类,会缓存一定的时间,在此时间之内,我们可以通过不同的方式 来获取此运行时类。

如何操作运行时类中的指定的属性

@Test
public void testField1() throws Exception{
   Class<Person> clazz = Person.class;
   //创建运行时类的对象
   Person person = clazz.newInstance();

   //1.getDeclaredField(String fieldName):获取运行时类中指定变量名的属性
   Field name = clazz.getDeclaredField("name");

   //2.保证当前属性是可访问的
   name.setAccessible(true);

   //3.获取、设置指定对象的此属性值
   name.set(person, "Tom");
   Object o = name.get(person);
   System.out.println(o);
}

如何操作运行时类中的指定的方法

/*
   如何操作运行时类中的指定的方法 -- 需要掌握
    */
   @Test
   public void testMethod() throws Exception{
       Class<Person> clazz = Person.class;
       //创建运行时类的对象
       Person person = clazz.newInstance();

       /*
       1.获取指定的某个方法
       getDeclaredMethod():参数1:指明获取的方法的名称 参数2:指明获取的方法的形参列表
        */
       Method show = clazz.getDeclaredMethod("show", String.class);
       //2.保证当前方法是可访问的
       show.setAccessible(true);
       /*
       3.调用方法的invoke():参数1:访问的调用者 参数2:给方法形参赋值的实参
       invoke()的返回值即为对应类中调用的方法的返回值
        */
       Object returnVal = show.invoke(person, "CHN");
       System.out.println(returnVal);


       System.out.println("*************调用静态方法**************");
       //private static void display()

       Method display = clazz.getDeclaredMethod("display");
       display.setAccessible(true);
       //如果调用的运行时的类中的方法没有返回值,则此invoke()返回null
       Object returnVal1 = display.invoke(Person.class);
//       Object returnVal1 = display.invoke(null);
       System.out.println(returnVal1);//null

  }
posted @ 2022-03-06 23:39  阳光真好的博客  阅读(25)  评论(0)    收藏  举报