java反射机制介绍与应用

Java反射机制介绍与应用

1.对象创建的几种方法(显式)

  1. 用new语句创建对象,这是最常用的创建对象的方式。
  2. 调用对象的clone()方法。
  3. 运用反序列化手段,调用java.ioObjectinputStream对象的readObject()方法。
  4. 运用反射手段,调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法。

2.反射概念

(1)Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法。本质是JVM得到class对象之后,再通过class对象进行反编译,从而获取对象的各种信息。

(2)Java属于先编译再运行的语言,程序中对象的类型在编译期就确定下来了,而当程序在运行时可能需要动态加载某些类,这些类因为之前用不到,所以没有被加载到JVM。通过反射,可以在运行时动态地创建对象并调用其属性,不需要提前在编译期知道运行的对象是谁。

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取信息以及动态调用对象的方法的功能称为java语言的反射机制

反射的作用动态获取类的信息,进一步实现需要的功能。

原理:反射

3.反射相关API

注意以下API除了Class类外,其他类都位于java.lag.reflect包中。

1.Class类型

一旦class文件被加载到内存,就会为其创建一个Class对象。任何类被使用时都会创建一个Class对象。

Class类是java反射机制的基础,通过Class类,可以得到一个类的基本信息。

获得Class类实例的常用方法

  1. getClass方法:通过对象向获得Class实例。

            Users users1 = new Users();
            Users users2 = new Users();
            Class uclass1 = users1.getClass();
            Class uclass2 = users2.getClass();
            System.out.println(uclass1);//class com.ff.webpro.reflect.Users
            System.out.println(uclass2);//class com.ff.webpro.reflect.Users
            System.out.println(uclass1 == uclass2);//true
    
  2. 类名.class方式:通过类名获得Class实例。

            Class uclass1 = Users.class;
            System.out.println(uclass1);//class com.ff.webpro.reflect.Users
    
  3. Class类的静态方法 forName(String name):通过类型获得Class实例

            String className = "com.ff.webpro.reflect.Users";
            Class uclass = Class.forName(className);
            System.out.println(uclass);//class com.ff.webpro.reflect.Users
    
2.Constructor构造方法

通过getXXX方法获得构造方法的基本信息。

newInstance(Object… initargs) :创建实例

  1. 获得无参构造方法(public)

            String className = "com.ff.webpro.reflect.Users";
            Class uclass = Class.forName(className);        
            Constructor constructor = uclass.getConstructor();//默认获得的是无参构造方法(public)
            Users users = (Users) constructor.newInstance();//创建对象
    
  2. 获得有参构造方法(public)

            String className = "com.ff.webpro.reflect.Users";
            Class uclass = Class.forName(className);
            Constructor constructor = uclass.getConstructor(int.class, String.class);
            Users users = (Users) constructor.newInstance(23, "张三");
    
  3. 获得有参构造方法(private)

            String className = "com.ff.webpro.reflect.Users";
            Class uclass = Class.forName(className);
            Constructor constructor = uclass.getDeclaredConstructor(String.class,int.class);
            constructor.setAccessible(true);//设置访问权限,可以访问private,
            Users users = (Users) constructor.newInstance("张三",23);
    

注意:getDeclaredConstructor方法和getConstructor方法的区别

getDeclaredConstructor(Class<?>… parameterTypes)这个方法会返回制定参数类型的所有构造器,包括public的和非public的,当然也包括private的。getDeclaredConstructors()的返回结果就没有参数类型的过滤了。

getConstructor(Class<?>… parameterTypes)这个方法返回的是上面那个方法返回结果的子集,只返回制定参数类型访问权限是public的构造器。getConstructors()的返回结果同样也没有参数类型的过滤。

Constructor[]数组遍历

        Constructor[] declaredConstructors = uclass.getDeclaredConstructors();
        for (Constructor con:declaredConstructors){
            con.setAccessible(true);
            //具体操作
        }
3.Method方法

Method类将类中的方法进行封装,可以动态获得方法的信息,动态调用某一个对象的具体方法invoke

getName:获得方法名字
getParameterTypes:获得方法参数类型

invoke(Object obj, Object… args) :使用obj调用该方法,参数为args

Method实例都是通过Class类的方法获得
Method getMethod(String name, Class… parameterTypes) :通过指定方法名,参数类型,返回一个Method实例

String className = "com.ff.webpro.reflect.Users";
        Class uclass = Class.forName(className);
        Users users = (Users) uclass.newInstance();

        /*
          获得public方法
        */
        Method eatm = uclass.getMethod("eat");
        eatm.invoke(users);//使用users对象调用方法
        /*
          获得public方法,并传参
        */
        Method eatm = uclass.getMethod("eat",String.class);
        eatm.invoke(users,"aaa");
        /*
          获得private方法,并传参
        */
        Method eatm = uclass.getDeclaredMethod("eat",int.class,String.class);
        eatm.setAccessible(true);
        eatm.invoke(users,100,"jim");

Method方法遍历

        String className = "com.ff.webpro.reflect.Users";
        Class uclass = Class.forName(className);
        Users users = (Users) uclass.newInstance();

        Field[] fs = uclass.getDeclaredFields();
        for (Field f : fs
        ) {
            String name = f.getName();
            Method declaredMethod = uclass.getDeclaredMethod("get"+String.valueOf(name.charAt(0)).toUpperCase()+name.substring(1));//getName方法
            System.out.println(declaredMethod.invoke(users));
            
        }

4.Field属性

Field类将类的属性进行封装,可以获得属性的基本信息、属性的值,也可以对属性进行赋值。

getName:返回属性的名字
Set:设置属性值

        String className = "com.ff.webpro.reflect.Users";
        Class uclass = Class.forName(className);
        Users users = (Users) uclass.newInstance();
        Field numf =uclass.getField("num");//获得指定的公共的成员变量
              numf.set(users,100);
        Field namef = uclass.getDeclaredField("name");//获得指定的私有成员变量
        namef.setAccessible(true);
        namef.set(users,"jim");

Field[]数组遍历

        Field[] fs = uclass.getDeclaredFields();
        for (Field f : fs
        ) {
            f.setAccessible(true);
            //具体操作
        }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值