反射机制

一.简介

反射机制是Java动态性之一。

 

所谓动态语言:是指程序在运行时可以改变其结构:新的函数可以引进,已有的函数可以被删除等结构上的变化。比如常见的JavaScript就是动态语言,除此之外Ruby,Python等也属于动态语言,而C、C++则不属于动态语言。

 

从动态语言能在运行时改变程序结构结构或则变量类型上看,Java和C、C++一样都不属于动态语言。 但是JAVA却有一个非常突出的与动态相关的机制:反射机制。Java通过反射机制,可以在程序运行时加载,探知和使用编译期间完全未知的类,并且可以生成相关类对象实例,从而可以调用其方法或则改变某个属性值。所以JAVA也可以算得上是一个半动态的语言。

 

 

 

 

 

二.反射

 

1.反射机制概念

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

 

 

 

2.反射的应用场合 

在Java程序中许多对象在运行时都会出现两种类型:编译时类型和运行时类型。 编译时的类型由声明对象时实用的类型来决定,运行时的类型由实际赋值给对象的类型决定。

如:Person p=new Student();

其中编译时类型为Person,运行时类型为Student。 

除此之外,程序在运行时还可能接收到外部传入的对象,该对象的编译时类型为Object,但是程序有需要调用该对象的运行时类型的方法。为了解决这些问题,程序需要在运行时发现对象和类的真实信息。然而,如果编译时根本无法预知该对象和类属于哪些类,程序只能依靠运行时信息来发现该对象和类的真实信息,此时就必须使用到反射了。

 

 

 

3.反射涉及类

<1> 类:Class

      作用:反射的核心类,可以获取类的属性,方法等信息。

 

<2> 类:Field

       作用:Java.lang.reflec包中的类,表示类的成员变量,可以用来获取和设置类之中的属性值。

 

<3> 类:Method

       作用:Java.lang.reflec包中的类,表示类的方法,它可以用来获取类中的方法信息或者执行方法。

 

<4> 类:Constructor

       作用:Java.lang.reflec包中的类,表示类的构造方法。

 

 

 

 

三.代码实现

1.利用反射机制获取类信息

Java Bean

package com.wjn.sqlitedemo.bean;

public class Student implements Cloneable {

    private String name;
    private String sex;
    private String age;

    public Student(){

    }

    public Student(String name,String sex,String age){
        this.name=name;
        this.sex=sex;
        this.age=age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAge() {
        return age;
    }

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

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public String toString(){
        return "姓名:"+name+"  性别:"+sex+"  年龄:"+age;
    }
}

 

测试方法

public void reflectionMethod(){
    try {
         //1.利用Class.forName("类的全路径")方法获取Class对象
         Class myclass=Class.forName("com.wjn.sqlitedemo.bean.Student");

         //2.利用Method获取Student类的所有方法信息
         Method[] method=myclass.getDeclaredMethods();
         for(Method m:method){
            Log.d("TAG","类的所有方法信息:"+m.toString());
         }

            Log.d("TAG","********************************************************************");

         //3.利用Field获取Student类的所有成员属性信息
         Field[] field=myclass.getDeclaredFields();
         for(Field f:field){
             Log.d("TAG","类的所有成员属性信息:"+f.toString());
             System.out.println(f.toString());
         }

            Log.d("TAG","********************************************************************");

         //4.利用Constructor获取Student类的所有构造方法信息
         Constructor[] constructor=myclass.getDeclaredConstructors();
         for(Constructor c:constructor){
             Log.d("TAG","类的所有构造方法信息:"+c.toString());
             System.out.println(c.toString());
         }

     } catch (ClassNotFoundException e) {
         e.printStackTrace();
     }
}

 

结果

类的所有方法信息:public static java.lang.Object com.wjn.sqlitedemo.bean.Student.access$super(com.wjn.sqlitedemo.bean.Student,java.lang.String,java.lang.Object[])
类的所有方法信息:public java.lang.Object com.wjn.sqlitedemo.bean.Student.clone() throws java.lang.CloneNotSupportedException
类的所有方法信息:public java.lang.String com.wjn.sqlitedemo.bean.Student.getAge()
类的所有方法信息:public java.lang.String com.wjn.sqlitedemo.bean.Student.getName()
类的所有方法信息:public java.lang.String com.wjn.sqlitedemo.bean.Student.getSex()
类的所有方法信息:public void com.wjn.sqlitedemo.bean.Student.setAge(java.lang.String)
类的所有方法信息:public void com.wjn.sqlitedemo.bean.Student.setName(java.lang.String)
类的所有方法信息:public void com.wjn.sqlitedemo.bean.Student.setSex(java.lang.String)
类的所有方法信息:public java.lang.String com.wjn.sqlitedemo.bean.Student.toString()
********************************************************************
类的所有成员属性信息:private java.lang.String com.wjn.sqlitedemo.bean.Student.age
类的所有成员属性信息:private java.lang.String com.wjn.sqlitedemo.bean.Student.name
类的所有成员属性信息:private java.lang.String com.wjn.sqlitedemo.bean.Student.sex
类的所有成员属性信息:public static transient volatile com.android.tools.ir.runtime.IncrementalChange com.wjn.sqlitedemo.bean.Student.$change
类的所有成员属性信息:public static final long com.wjn.sqlitedemo.bean.Student.serialVersionUID
********************************************************************
类的所有构造方法信息:public com.wjn.sqlitedemo.bean.Student()
类的所有构造方法信息:public com.wjn.sqlitedemo.bean.Student(java.lang.String,java.lang.String,java.lang.String)
类的所有构造方法信息:com.wjn.sqlitedemo.bean.Student(java.lang.Object[],com.android.tools.ir.runtime.InstantReloadException)

 

 

 

2.利用反射机制创建类对象

Java Bean

package com.wjn.sqlitedemo.bean;

public class Student implements Cloneable {

    private String name;
    private String sex;
    private String age;

    public Student(){

    }

    public Student(String name,String sex,String age){
        this.name=name;
        this.sex=sex;
        this.age=age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAge() {
        return age;
    }

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

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public String toString(){
        return "姓名:"+name+"  性别:"+sex+"  年龄:"+age;
    }
}

 

 

测试方法

public void reflectionMethods(){
     //1.利用Class.forName("类的全路径")方法获取Class对象
     Class myclass= null;
     try {
          myclass = Class.forName("com.wjn.sqlitedemo.bean.Student");
          //2.利用get set方法创建对象
          Student student= null;
          try {
              student = (Student) myclass.newInstance();
          } catch (InstantiationException e) {
              e.printStackTrace();
          } catch (IllegalAccessException e) {
              e.printStackTrace();
          }
          student.setName("张三");
          student.setSex("男");
          student.setAge("27");
          Log.d("TAG","利用get set方法创建对象获取类信息:"+student.toString());

            Log.d("TAG","********************************************************************");

          //3.利用构造方法创建对象
          Constructor cc = myclass.getDeclaredConstructor(String.class,String.class,String.class);
          Student student1= (Student) cc.newInstance("李四","男","29");
          Log.d("TAG","利用构造方法创建对象取类信息:"+student1.toString());
      } catch (ClassNotFoundException e) {
          e.printStackTrace();
      } catch (NoSuchMethodException e) {
          e.printStackTrace();
      } catch (InstantiationException e) {
          e.printStackTrace();
      } catch (IllegalAccessException e) {
          e.printStackTrace();
      } catch (InvocationTargetException e) {
          e.printStackTrace();
      }
}

 

结果

利用get set方法创建对象获取类信息:姓名:张三  性别:男  年龄:27
********************************************************************
利用构造方法创建对象取类信息:姓名:李四  性别:男  年龄:29

 

 

图解

 

 

 

3.Android中使用反射机制

工具类

public static int getIdByName(Context context, String className, String resName) {
     String packageName = context.getPackageName();
     int id = 0;
     try {
         Class r = Class.forName(packageName + ".R");
         Class[] classes = r.getClasses();
         Class desireClass = null;
         for (Class cls : classes) {
             if (cls.getName().split("\\$")[1].equals(className)) {
                 desireClass = cls;
                 break;
             }
         }
         if (desireClass != null) {
             id = desireClass.getField(resName).getInt(desireClass);
         }
     } catch (Exception e) {
         e.printStackTrace();
     }
     return id;
}

 

使用

setContentView(MResource.getIdByName(this, "layout", "activity_connectdevice"));


datalayout= (LinearLayout) findViewById(MResource.getIdByName(this, "id", "activity_connectdevice_datalayout"));


pdflayout= (LinearLayout) findViewById(MResource.getIdByName(this, "id", "activity_connectdevice_pdflayout"));

Android的反射机制是在本人打包Android原生代码封装成Cordova插件时用到的。

 

 

Cordova 知识讲解:https://blog.csdn.net/weixin_37730482/article/category/7007517

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值