反射

什么是反射

Java中提供的一套类库,通过这套类库

  • 运行时动态获取类中的信息
  • 运行时动态调用构造函数创建对象
  • 运行时动态访问(调用)对象的方法和属性

这种运行期间动态获取类中的信息(属性,方法,包.注解(@Test)等),以及动态调用对象的方法和属性的功能称之为Java语言的>反射机制,通俗理解,在运行期间对类的内容进行操作

Class类

想要使用反射,就要获取到类中的所有信息(属性方法等)
在Java中有一个特殊的类类型叫做:Class
此类型的对象存储的是某个类中的信息
比如

Class clazz1=Class.forName("cn.tedu.Student");
clazz1是一个对象,此对象中存储的都是数据,这些数据都是Student中的属性和方法
	属性:访问修饰符,类型,属性名
	方法:访问修饰符,返回值类型,方法名(参数列表);
Class clazz2=Class.forName("cn.tedu.User");
clazz2是一个对象,对象中存储的是User类中的属性和方法

Class类是Java提供的,这个Class类可以表达一个类的信息(属性方法等类中的信息)

  • 每个类加载后(方法区),系统都会为该类生成一个对应的Class类类型的对象
    这个对象是存储在堆区中,通过该Class对象可以访问方法区中的类的信息

  • 一旦获取了某个类Class类型的对象之后,程序员可以写程序调用Class对象中的API方法
    获取该Class对象中的类的信息

如何获取Class类型的对象

  • 对象.getClass();
    比如:
User user=new User();
Class clazz1=user,getClass();
  • 类名.class
    比如:
User user=new User();
Class clazz1=User.Class();
  • Class.forName(“包名.类名”);
    比如
Class clazz=Class.forName("包名.类名");

此种情况分为两步
1. 加载类User ,进入方法区,创建Class类型的对象
2. 返回Class类型的对象

用以上的三种方式可以获取到Class类型的对象

User类:
public class User {
    private String userName;
    private String userPassword;
    String userAddress;
    protected int age;
    public String desc;
    public User(){}
    public User(String userName, String userPassword, String userAddress, int age, String desc) {
        this.userName = userName;
        this.userPassword = userPassword;
        this.userAddress = userAddress;
        this.age = age;
        this.desc = desc;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserPassword() {
        return userPassword;
    }

    public void setUserPassword(String userPassword) {
        this.userPassword = userPassword;
    }

    public String getUserAddress() {
        return userAddress;
    }

    public void setUserAddress(String userAddress) {
        this.userAddress = userAddress;
    }

    public int getAge() {
        return age;
    }

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

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }
    private float xxx(int a,float b){
        return 0;
    }
    protected void yyy(String a,double b){

    }
    String zzz (String a, Date date){
        return null;
    }
}


测试类

public class TestReflectClass {
	@Test
    public void testMethod1(){
            User user=new User();
            user.setUserName("zhangsan");
            user.setUserPassword("123");
            System.out.println(user.getUserName()+" "+user.getUserPassword());
	}
    /**
     * 反射的做法,首要要得到Class类型的对象
     * 此对象,在类加载后自动有jvm创建,并把对象放在堆中
     * 程序员只是通过api获取Class对象
     */
     @Test
    public void testMethod2() throws Exception{
        //方式一
        User user=new User();
        Class clazz1=user.getClass();

        //方式二
        Class clazz2=User.class;

        //方式三
        Class clazz3=Class.forName("day20.jdk.reflect.User");
        //输出hashCode,hashCode值一样,证明此Class的对象只有一个
        System.out.println(clazz1);
        System.out.println(clazz2);
        System.out.println(clazz3);
        System.out.println(ArrayList.class.hashCode());
    }
    @Test
    public void testMethod3() throws Exception{
        Class clazz=Class.forName("day20.jdk.reflect.User");

    }
}

通过Class类型的对象获取如下:

  • Filed类;代表的是成员变量,即属性
  • Method类:代表的是方法
  • Constructor类:代表的是构造函数
  • Annotation类:代表的是注解

通过以上的类的api获取对应的信息

  • 可以获取Filed中的信息,获取类的属性,属性的修饰符,属性的类型,属性的名称
  • 可以获取Method中的信息,获取该类的方法,修饰符,返回值类型,方法名,参数列表
  • 可以获取Constructor中的你想逆袭,获取类的构造函数,修饰符,构造函数的参数列表
  • 可以获取Annotation中的信息,获取类的注解,注解的名称,朱恩杰的属性值

结论

在运行期间通过Class对象调用反射的api可以反射实例化对象
可以反射访问属性,和反射调用方法
总之编译期间能写的代码,用反射也能实现

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值