Java 反射学习笔记

一、反射是什么

反射,指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对任意一个对象,都能调用它的任意一个方法。这种动态获取信息,以及动态调用对象方法的功能,叫做java语言的反射机制;简而言之,反射就是获取Class类对象及其内部信息(方法,属性,构造函数)以及反向控制实例对象的能力

二、反射原理

  • 我们编写的java项目,在运行前会编译源文件成为一个个.class文件(字节码文件)
  • 在运行时,这些字节码文件会被ClassLoader加载器加载到JVM中,然后通过jvm指令运行起来;此时JVM会在内存中创建一个Class对象
  • 我们可以通过Class对象获取Field(成员变量),Methos(成员方法),Constructor(构造函数)

三、反射使用

1.Class对象的获取

class对象的获取一般有三种

  • System.out.println(Test.class);
  • System.out.println(new Test().getClass());
  • System.out.println(Class.forName("com.atguigu.test8.Test"));

运行结果:

在这里插入图片描述

2.获取类的成员变量信息

方法用途
getField(String name)获得某个公有属性对象
getFields()获得所有公有属性对象
getDeclaredField(String name)获得某个属性对象(public和非public)
getDeclaredFields()获得所有属性对象(public和非public)
public class Test {
    private String name;
    public String email;
    public String getName(){
        return this.name;
    }
    public void setName(String name){
        this.name = name;
    }
    public static void main(String[] args) throws Exception {
        Class clz = Class.forName("com.atguigu.test8.Test");
        Test test = (Test) clz.newInstance();
        Field[] fields = clz.getDeclaredFields();
        for(Field field : fields){
            System.out.println(field);
        }
    }
}

打印结果
在这里插入图片描述

3.获取类的方法

方法用途
getMethod(String name,Class…<?>parameterTypers)获得该类的某个公有方法
getMethods()获得该类的所有公有方法
getDeclaredMethod(String name,Class…<?>parameterTypers)获得该类的某个方法(public和非public)
getDeclaredFields()获得所有属性对象(public和非public)
public class Test {
    private String name;
    public String email;
    public String getName(){
        return this.name;
    }
    public void setName(String name){
        this.name = name;
    }
    public static void main(String[] args) throws Exception {
        Class clz = Class.forName("com.atguigu.test8.Test");
        Test test = (Test) clz.newInstance();
        Method[] methods = clz.getMethods();
        for(Method method : methods){
            System.out.println(method);
        }
    }
}

打印结果
在这里插入图片描述

3.获取类的构造函数

方法用途
getConstructor(Class…<?>parameterTypers)获得类中与参数类型匹配的公有构造方法
getConstructors()获得该类的所有公有构造方法
getDeclaredConstructor(Class…<?>parameterTypers)获得该类中与参数类型匹配的构造方法
getDeclaredConstructors()获得该类所有构造方法
public class Test {

    private String name;
    public String email;
    public Test(String name,String email){}
    public Test(){}

    public static void main(String[] args) throws Exception {
        Class clz = Class.forName("com.atguigu.test8.Test");
        Test test = (Test) clz.newInstance();
        Constructor[] constructors = clz.getConstructors();
        for(Constructor constructor : constructors){
            System.out.println(constructor);
        }
        Constructor constructor = clz.getConstructor(String.class,String.class);
        Test test1 = (Test) constructor.newInstance("小明","123@qq.com");
        System.out.println(test1);
    }

打印结果
在这里插入图片描述

四、反射实例

这里介绍一下Spring的IOC原理

1、Spring 在项目启动的时间通过读取xml中配置的bean的路径,

2、然后通过Class.forName 读取class 到类加载器,

3、然后通过反射创建所有的bean实例并保存到容器中,启动容器之后,

4、在项目中可以直接获取bean对象。

下面是大概实现此过程的代码

public class ClazzTest {
  public static void main(String[] args){
      try {
          Map<String,Object> container = new HashMap<>();
          //1.读取配置
          InputStream in = ClazzTest.class.getResourceAsStream("/beans.properties");
          Properties property = new Properties();
          property.load(in);
          //2.反射创建对象
          Set<Object> keySet = property.keySet();
          for (Object key : keySet) {
              // 2.1 获取类的全路径
              String classStr = (String) property.get(key);
              // 2.2 加载class 到虚拟机
              Class<?> beanClazz = Class.forName(classStr);
              // 2.3 获取缺省的构造函数
              Constructor<?> declaredConstructor = beanClazz.getDeclaredConstructor();
              // 2.4 创建实例
              Object o = declaredConstructor.newInstance();
              container.put((String) key,o);
          }
          // 3.获取实例
          Npc npc = (Npc) container.get("npc");
          System.out.println(npc == null);
      } catch (Exception e) {
          e.printStackTrace();
      }
  }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值