Reflection反射概念和Class类

Reflection反射:

          1. 理解Class类并获取Class实例

          2. 创建运行时的对象

          3. 调用运行时类的指定结构

          4. 动态语言的关键

                反射机制允许程序在执行期借助Reflection API取得任何的内部信息,

                并能直接操作任意对象的内部属性及方法。

      我们可以通过这个对象看到类的结构, 对象就像一面镜子,通过这个镜子看到类的结构,

      所以,我们形象的称之为:反射

          正常方式:引入需要的“包类”名称---->通过new实例化----->取得实例化对象

          反射方式:实例化对象---->getClass()方法-------->得到完整的“包类”名称

                    java不是动态语言,但java可以称之为”准动态语言“

             java反射机制提供的功能:1. 在运行时判断任意一个对象所属的类

                                                        2. 在运行时构造任意一个类的对象

                                                        3. 在运行时判断任意一个类所具有的成员变量和方法

                                                        4. 在运行时获取泛型信息

                                                        5. 在运行时调用任意一个对象的成员变量和方法

                                                        6. 在运行时处理注解

                                                        7. 生成动态代理

  • 反射相关的主要API: java.lang.Class:代表一个类

                                              java.lang.reflect.Method:代表类的方法

                                              java.lang.reflect.Field:代表类的成员变量

                                              java.lang.reflect.Constructor:代表类的构造器

     哪些类型可以有Class对象:class, interface,[],enum,annotation,primitive type(基本数据类型),void

package Reflection1;

public class Person
{
   @Override
   public String toString()
  {
       return "Person{" +
               "name='" + name + '\'' +
               ", age=" + age +
               '}';
  }

   private String name;
   public int age;

   public String getName() {
       return name;
  }

   public void setName(String name)
  {
       this.name = name;
  }

   public int getAge()

  {
       return age;
  }

   public void setAge(int age)
  {
       this.age = age;
  }

   public Person(String name, int age)
  {
       this.name = name;
       this.age = age;
  }
   private Person(String name)
  {
       this.name = name;
       this.age = age;
  }

   public void show()
  {
       System.out.println("你好,我是一个人");
  }
   private String showNation(String nation)
  {
       System.out.println("我的国籍是"+nation);
       return nation;
  }
}

package Reflection1;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/*

*/
public class ReflectionTest
{
 //   反射之前,对于Person的操作
   public void test1()
  {
       //1.创建Porson类的对象
       Person person=new Person("Tom",12);
       //2. 通过对象,调用其内部的属性和方法
       person.age=10;
       System.out.println(person.toString());//调方法
       person.show();
       //在Rerson类外部,不可以通过Person类的对象调用其内部私有结构
       //比如:name,showNation(),以及私有的构造器

  }


   //反射之后,对于Person的操作   反射做的事
   public void test2() throws Exception {
       Class personClass = Person.class;
       //1.通过反射,创建Person类的对象
       Constructor constructor= personClass.getConstructor(String.class,int.class);//找到构造器   ,因为上面对象String,int类型
       Object obj= constructor.newInstance("Ton", 12);
       Person p=(Person) obj;//强转
       System.out.println(p.toString());

       //2.通过反射,调用对象指定的属性,和方法
       //调用属性
       Field age = personClass.getDeclaredField("age");
           age.set(p,10);
       System.out.println(p.toString());

       //调用方法
       Method show = personClass.getDeclaredMethod("show");
             show.invoke(p);

       System.out.println("************************");

             //通过反射:可以调用Person类的私有结构的,比如:私有的构造器,方法,属性
       //调用私有的构造器
       Constructor declaredConstructor = personClass.getDeclaredConstructor(String.class);
            declaredConstructor.setAccessible(true);
             Person p1=(Person)declaredConstructor.newInstance("jerry");
       System.out.println(p1);

       //调用属性
       Field name = personClass.getDeclaredField("name");
         name.set(p1,"HaMeimei");
       System.out.println(p1);

       //调用私有的方法
       Method showNation = personClass.getDeclaredMethod("showNation", String.class);
       showNation.setAccessible(true);
       String nation=(String)showNation.invoke(p1,"中国");//调用,,相当于String nation= p1.showNation("中国");
       System.out.println(nation);

  }

   //疑问1:通过直接mew的方式或反射的方式都可以调用公共的结构,开发中到底用哪个?
   //建议:直接new的方式
   //什么时候会使用:反射的方式 反射的特征:动态性.
   //程序服务器运行跑起来了,通过浏览器来访问后台,访问的时候有可能是登录或者注册不知道你到底要干些什么,
   // 如果要登录,就把登录请求发送过去,java里面就获取你想干什么事,然后就造登录的对象,
   // 就是你发过来什么,就造什么样的对象,就调相关的方法(这就动态性的,就用反射来做)

   //疑问2:反射机制于面向对象中的封装属性是不是矛盾
   //不矛盾,

       /*
       关于java.lang.Class类的理解
       1. 类的加载过程:程序经过javac.exe命令以后,会生成多个字节码文件(.class结尾),
                     接着我们使用 java.exe命令对某个字节码文件进行解析运行。相当于将某个字节码文件加载
                     到内存中此过程称为类的加载。加载到内存中的类,我们就称为运行时类,此运行时类,就作为Class的一个实例
       2. Class实例就对应着一个运行时类。
      3. 加载到内存中的运行时落类,会缓存一定的时间,在此时间之内,我们可以通过不同的方法来获取此运行时类
        */

   //万事万物皆对象 对象.xxx,File,URL,反射,前端,数据库操作等
   //获取Class的实例的方式(前三种方式需要掌握)
   public void test3() throws ClassNotFoundException {
//       方式1:调用运行时类的属性,class
       Class<Person> class1=Person.class;
       System.out.println(class1);

       //方式2:通过运行时类的对象,调用getClass()方法
        Person p1=new Person();
       Class<? extends Person> aClass = p1.getClass();
       System.out.println(aClass);
        //方式3:调用Class的静态方法:forName(String calssPath)
       Class<?> aClass1 = Class.forName("Reflection1.Person");
       System.out.println(aClass1);
       //方式4:使用类的加载器 :classLoader
       ClassLoader classLoader = ReflectionTest.class.getClassLoader();
       Class<?> aClass2 = classLoader.loadClass("Reflection1.Person");
       System.out.println(aClass2);

  }

}
 
posted @   zjw_rp  阅读(85)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示