java中的反射

java中很多框架都用到了反射,所以在造spring轮子之前,还是要彻底的了解一下反射。

1.什么是反射?(what)

在学习任意一个技术时,我们可以去官网看它的介绍,而不是先去百度。

官网反射介绍:https://www.oracle.com/technetwork/articles/java/javareflection-1536171.html

介绍如下:

Reflection is a feature in the Java programming language. It allows an executing Java program to examine or "introspect" upon itself, and manipulate internal properties of the program. For example, it's possible for a Java class to obtain the names of all its members and display them。

反射式java编程语言的一个特性,它允许java程序在运行时进行自我检查并操作程序内部的属性。例如,对于java类我们可以获得它所有成员的名字并展示它们。

2.为什么会有反射?(why)

了解了什么事反射后,能知道我们可以通过反射获取类的所有成员和方法,并且调用,这就能做很多事情了。

3.怎么去使用反射?(How)

那么怎么调用呢?要先获取到该类的字节码文件对象,就是.class文件。 在程序运行期间,JVM始终为所有的对象维护一个类型标识,这个标识跟踪着这个对象所属的类,而保存这些信息的类就是Class类。

首先贴上我这里用于测试的简单Person类:

public class Person {
    public String name;

    public Person(String name){
        this.name = name;
    }
    public Person(){}
    
    public void say(){
        System.out.println("I am a person,I can say Hello,World.");
    }
    
    public String getName() {
        return name;
    }

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

 

我们如何获取Class类呢?一般有三种方式:

        //1.通过类.class语法,静态加载
        Class clazz1 = Person.class;
        System.out.println(clazz1);

        //2.通过对象.getClass(),静态加载
        Class clazz2 = new Person().getClass();
        System.out.println(clazz2);

        //3.通过Class.forName("限定类名"); 动态加载
        Class clazz3 = Class.forName("com.jts.study.reflect.Person");
        System.out.println(clazz3);

在开发中我们用反射都是用的第三种。因为前两种本来类就知道了,就没必要再用反射了。

获得Class类后,我们就可以做很多事情了。

几种常见的对类的类型的判断:

clazz.isInterface();//判断是否是接口
clazz.isAnnotation();//类型是否是注解
clazz.isArray();//类型是否是数组
clazz.isAnnotation();//判断是否是注解
//类上是否有JRequestMapping注解,我们使用的注解开发基本都是基于这个方法去判断的
clazz.isAnnotationPresent(JRequestMapping.class);

clazz.isEnum();//类型是否是枚举类型
clazz.isPrimitive();//类型是否是原始数据类(boolean,byte,short,char,int,float,double,long)

拿到一个类的class之后,如果去实例化这个类呢?
 

//如果是无参构造器,直接用clazz.newInstance()方法即可。
Person person = (Person)clazz.newInstance();

//如果是有参构造器,类似于这样的呢
Constructor constructor = clazz.getConstructor(String.class);
Person sss = (Person)constructor.newInstance("my name is lily");
System.out.println(sss.getName());
 
  • 获取类的字段并调用,用Field类
Class<?> clazz = Class.forName("com.jts.study.reflect.Person");
Person person = (Person)clazz.newInstance();
Field field = clazz.getDeclaredField("name");
//getDeclaredField可以获取private 声明的变量,而getField不可以 
field.setAccessible(true);//配合getDeclaredField()方法一起使用。 
field.set(person,"field test"); //给字段赋值
System.out.println(person.getName());

//获取类的所有字段信息
Field[] declaredFields = clazz.getDeclaredFields();
  • 获取类的方法并调用,用Method类

无参方法获取并调用:
    

      Class<?> clazz = Class.forName("com.jts.study.reflect.Person");

      Person person = (Person)clazz.newInstance();
      person.setName("reflect method test");

      Method getName = clazz.getDeclaredMethod("getName");//获取无参方法
      Object result1 = getName.invoke(person);//无参方法调用(有返回值)
      System.out.println(result1);

有参方法获取并调用:

     

      Method setName = clazz.getDeclaredMethod("setName", String.class);//获取有参方法
      setName.invoke(person, "set name test");//有参方法调用
      System.out.println(person.getName());

总结:Java反射机制是指java程序在运行过程中,可以获取任意一个类的相关信息,并且能够调用其方法和属性。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值