JAVA--反射介绍

反射对JAVA这种具有动态性(java有动态性但不是动态语言,js和python是动态语言)的语言也有着巨大的使用价值。一下为java反射机制的学习总结。

什么是反射
反射的“反”是相对于普通运行时对象的引用来说的。在正常使用一个类时,我们需要提前了解这个类有什么方法,有哪些属性。而利用反射我们在运行时才了解该类有什么方法和属性。

    @Test
    public void TestThree() throws Exception{


        //正常调用
        Person person1 = new Person();
        System.out.println(person1);

        //通过Class反射调用
        Class c2 = Person.class;
        Person person2 = (Person) c2.newInstance();
        System.out.println(person2);


    }

在这里插入图片描述
通过反射,我们可以在程序中访问已经装载在JVM中的java对象,实现访问,检测,修改java对象本身的功能。

反射的使用
通过反射获取类对象的三种方式

  public void  TestTwo() throws  Exception{

        //通过persion实例获取
        Person preson1 = new Person();
        Class c1 = preson1.getClass();
        System.out.println(c1.getName());


        //通过presion类直接获取,不会执行静态代码块
        Class c2 = Person.class;
        System.out.println(c2);

        //通过Class的静态方法获取
        String classname = "com.company.Person";
        Class c3 = Class.forName(classname);
        System.out.println(c3);

    }


以上为常用的利用反射获取对象的三种方式,其中通过Person.class直接获取时不会执行静态代码块,以下代码将对此进行测试。


public class Person {
    public String name;
    public  int age;
    static {
        int a = 0;
        System.out.println(a);
    }
    在Person类中添加静态代码块
/----------------------------------------------/


 @Test
    public void  TestTwo() throws  Exception{

//        //通过presion实例获取
//        Person preson1 = new Person();
//        Class c1 = preson1.getClass();
//        System.out.println(c1.getName());


        //通过presion类直接获取,不会执行静态代码块
        Class c2 = Person.class;
        System.out.println(c2+"c2");

        //通过Class的静态方法获取
        String classname = "com.company.Person";
        Class c3 = Class.forName(classname);
        System.out.println(c3+"c3");

    }

在这里插入图片描述在通过.class调用时并未输出0,没用执行静态代码块,通过.forName调用时执行了静态代码块,并且静态代码块只会执行一次。

在程序运行时JVM中只有一个运行时类对象,也就是说上面的C1,C2,C3都是相等的。

在这里插入图片描述
通过反射获取构造方法
通过反射主要有两种方式获取构造方法。具体代码如下

    public void TestFour() throws  Exception{
        
        Class c1 = Person.class;

        //通过Class的newInstance获取构造函数(只能获取无参构造函数)
        Person person1 = (Person)c1.newInstance();

        //通过Constructor的newInstance获取构造函数(可以获取有参构造并传值)
        Constructor constructor = c1.getConstructor(String.class);
        Person person2 = (Person)constructor.newInstance("王二狗");
    }

其中通过Class直接获取时只能获得无参构造方法。使用Constructor获取构造方式时可以传入参数类型指定获取对应的构造方法。
在这里插入图片描述通过反射获取属性

@Test
    public  void TestFive()throws  Exception{

        Class c = Person.class;

        Person person = (Person) c.newInstance();

        //获取属性名称.传入的参数为属性名称(不能获取私有属性)
        Field field = c.getField("name");
        
        //为属性设置值
        field.set(person,"张三");

        System.out.println(field.get(person));

    }

通过以上方法只能获取非私有属性的值并赋值,要想获取私有属性的值需要用到

Field field1 =c.getDeclaredField("name");

获取方法

   public void  TestSix() throws  Exception{

        Class c = Person.class;

        Person person = (Person) c.newInstance();

        //获取方法,参数为方法名称(不能获取私有方法)
        Method method = c.getMethod("show1");
        //调用方法
        method.invoke(person);

        //获取含有参数的方法,参数为方法名称和参数类型
        Method method1 = c.getMethod("show3", int.class);
       //调用方法,参数为Object和传入的参数
        method1.invoke(person,10);

    }

在这里插入图片描述

调用有参和无参方法的方式如上代码所示,当调用私有方法时利用

 Method method = c.getDeclaredMethod("show1");

以上为反射的简单介绍和基础使用演示,对于反射还有更高级的内省,动态代理等运用,将在以后文章中介绍。如上述有错误请在评论中指出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值