反射

3 篇文章 0 订阅
1 篇文章 0 订阅

一、反射的核心思想:

将一个类中的各个成员映射成相应的java类型。如下图所示:
(所谓的成员包括:包、构造器、属性、普通方法等)

这里写图片描述

二、通过反射创建对象
<创建对象时一定会调用构造方法,因此先通过反射获取字节码(根基)
然后通过字节码来获取指定的构造方法,再通过构造器创建对象>

private static void test4() throws Exception {
    //获取Class对象
    Class personClass = Class.forName("zh.java.reflect1.Person");

    //1.用Class对象直接调用newInstance()创建对象
    Person person1 = Person.class.newInstance();
    System.out.println("用Class对象直接创建的对象:"+person1);

    //2.调用构造器创建对象
    //①获得无参的构造方法
    //getConstructor()是一个可变参数的方法,可以通过指定参数类型来获取某一具体的构造方法
    Constructor constructor1 = personClass.getConstructor();

    //创建对象person2:
    Person person2 = (Person) constructor1.newInstance();
    System.out.println("无参构造方法创建的对象:"+person2);

    //②通过字节码文件获取指定参数的构造方法
    Constructor constructor3 = personClass.getConstructor(String.class,int.class,float.class,double.class);

    //创建对象person3:
    Person person3 = (Person) constructor2.newInstance("李四",20,50,168.5);
    System.out.println("有参构造方法创建的对象:"+person3);
    }

*注:反射创建对象的效率比传统new对象的效率低很多;

三、通过反射来获取某一实体类对象中的属性字段

/*
getDeclaredFields():获取类中的所有字段,不包括父类声明的字段
getFields():获取某个类中所有的公共(public)字段,包括父类中的字段
*/
//获取、修改私有属性值,下面代码中的name为Person的私有属性
    Field field2 = personClass.getDeclaredField("name");
    System.out.println("修改name之前: "+person);

    field2.setAccessible(true); //setAccessible():设置属性的可访问性,可以修改私有属性的值
    field2.set(person, "王二");
    System.out.println("修改name之后: "+person);

//注:类似的方法还有
    getDeclaredConstructor() 与 getConstructor()
    getDeclaredMethod() 与 getMethod()

四、通过反射调用实体类中指定的方法,必须知道方法名。

/*
*通过反射获取实体类的所有方法,包括继承Object类的方法
**/
private static void test1() {
    Class dogClass = Dog.class;
    Method[] methods = dogClass.getMethods();
    for (Method method : methods) {
        System.out.println(method);
    }
}
运行结果:
public void zh.java.reflect.method.Dog.run()
public void zh.java.reflect.method.Dog.run(long)
public final void java.lang.Object.wait() throws java.lang.InterruptedException
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 boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
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()
/*
*通过反射调用实体类无参的普通方法
**/
private static void test2() throws Exception {
    Class dogClass = Dog.class;     
    // 实例方法是通过对象名调用的,因此先创建一个Dog对象
    Dog dog = (Dog) dogClass.newInstance();
    Method runMethod = dogClass.getMethod("run"); // 获取无参的方法,
    runMethod.invoke(dog); // 调用执行方法
}

/*
* 通过反射调用实体类的有参普通方法
**/
private static void test3() throws Exception {
    Class dogClass = Dog.class;     
    Dog dog = (Dog) dogClass.getDeclaredConstructor().newInstance();

    Method runMethodArgs = dogClass.getMethod("run", long.class); //参数是参数类型的字节码
    runMethodArgs.invoke(dog, 10);
}
运行结果:
Dog - run and run !   //调用无参方法
Dog - run and run 10 km!  //调用有参方法
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值