反射初简述

反射

一.概述

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.

Class对象的由来是将class文件读入内存,并为之创建一个Class对象。

Class实例对应着一个运行时类(加载到内存中的类)

  • 创建Class对象的三种方式
        //方式一:Class.forName("全类名")
        Class class1 = Class.forName("abstractExer.Employee");//包+类
        System.out.println(class1);

        //方式二:对象.getClass()
        Employee employee = new Employee();
        Class class2 = employee.getClass();
        System.out.println(class2);

        //方式三:类名.class
        Class class3 = Employee.class;
        System.out.println(class3);

        System.out.println(class1 == class2);    //true
        System.out.println(class1 == class3);    //true

结果

class abstractExer.Employee
class abstractExer.Employee
class abstractExer.Employee
true
true

二、通过反射创建对应运行时类的对象

使用方法newInstance()

        Class class1 = Class.forName("abstractExer.Employee");
        System.out.println(class1);
        Employee obj = (Employee) class1.newInstance();
        System.out.println(obj);

结果

class abstractExer.Employee
Employee{salay=0.0, hireDay=null}

要求

  • 运行时类必须提供空参构造器
  • 构造器权限通常为public

三、获取运行时属性结构及其内部结构

  • getFields():获取当前运行时类及其父类中声明为public访问权限的属性
  • getDeclaredFields():获取当前运行时类所有的属性(不包含父类属性)
        Class aClass=Person.class;
        //获取属性结构
        Field[] fields = aClass.getFields();
        for(Field f : fields)
        {
            System.out.println(f);
        }
		System.out.println(=================================)
		Field[] fields1 = aClass.getDeclaredFields();
        for(Field f : fields1)
        {
            System.out.println(f);
        }

public int reflect.Person.id
public java.lang.String reflect.Person.sex
public int reflect.UpPerson.money
=================================  
private java.lang.String reflect.Person.name
int reflect.Person.age
public int reflect.Person.id
public java.lang.String reflect.Person.sex
  • getMethods:获取当前运行时类及其父类中声明为public访问权限的方法
  • getDeclaredMethods():获取当前运行时类所有的方法(不包含父类属性)
        Class<Person> aClass = Person.class;
        Method[] methods = aClass.getMethods();
        for (Method m : methods )
        {
            System.out.println(m);
        }
		System.out.println(=================================)
		Method[] methods1 = aClass.getDeclaredMethods();
        for (Method m : methods1 )
        {
            System.out.println(m);
        }

print

public java.lang.String reflect.Person.toString()
public void reflect.Person.eat()
public int reflect.UpPerson.add()
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
=================================    
public java.lang.String reflect.Person.toString()
public void reflect.Person.eat()
  • getConstructors:获取当前运行时类中声明为public访问权限的构造器

  • getDeclaredConstructors:获取当前运行时类所有的构造器(不包含父类属性)

四、调用运行时类中的属性

getField()当前运行时类中声明为public的属性----不常用
Class<Person> aClass = Person.class;

        //创建运行时类的对象
        Person p = aClass.newInstance();
        //获取指定属性
        Field id1 = aClass.getField("id");
        /*
        设置当前属性
        set():  参数一:设置哪个对象的属性  参数二:将此属性设置为多少
         */
        id1.set(p,99);
        /*
        获取当前属性的值
        get(): 参数:获取那个对象的当前属性值
         */
        int id2 = (int) id1.get(p);
        System.out.println(id2); //99
getDeclaredField()获取运行时类中指定变量名的属性----常用
Class<Person> aClass = Person.class;
        //创建运行时类的对象
        Person p = aClass.newInstance();
        //1. getDeclaredField(String fieldName):获取运行时类中指定变量名的属性
        Field name = aClass.getDeclaredField("name");
        //2.保证当前属性是可以访问的
        name.setAccessible(true);
        //3.获取,设置指定对象的属性值
        name.set(p,"July");
        System.out.println(name.get(p));
调用运行时类中的指定的方法

invoke就是调用类中的方法,最简单的用法是可以把方法参数化invoke(class, method)。

        Class<Person> aClass = Person.class;
        //创建运行时类的对象
        Person p = aClass.newInstance();
        /*
        1.获取指定的某个方法
        getDeclaredMethod():参数1 :指明获取的方法的名称  参数2:指明获取的方法的形参列表
         */
        Method naion = aClass.getDeclaredMethod("naion", String.class);
        //2.保证当前方法是可访问的
        naion.setAccessible(true);
        /*
        3. 调用方法的invoke():参数1:方法的调用者  参数2:给方法形参赋值的实参
        invoke()的返回值即为对应类中调用的方法的返回值。
         */
        Object returnValue = naion.invoke(p,"CHN"); //String nation = p.show("CHN");
        System.out.println(returnValue);//CHN
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值