反射机制的使用

来源:互联网 发布:linux中重启mysql命令 编辑:程序博客网 时间:2024/05/17 08:38

   一:反射机制

         反射是java语言的特性,它允许程序在运行时,进行自我检查和对内部成员进行操作,并根据自身的状态和结果进行修改应用的行为状态和相关语义。

     

   常用到的方法:

   getDeclaredMethods(): 获取该反射类中所有的方法,返回一个String数组类型

            getReturnType():获取该方法的返回类型

           getParameterTypes():获取某方法的传入类型

            getDeclaredMethod("MethodName",class···);获取指定的方法,传入方法名和该方法需要出入的数据类型

   getDeclaredConstructors():获取该类所有的构造函数 ,返回一个String数组类型

   getDeclaredConstructor(class……):获取特定的构造函数,根据传入的数据类型来进行匹配

   getSuperclass():获取该类的父类

   getInterfaces():获取该类的实现接口

           getDeclaredFields():获取该类的所有属性 返回一个String类数组类型

    

   二.反射类的使用

      以下是反射的具体使用,获取如下类的具体方法和属性

public class ReflectionTest {//属性private String mName="hjo";private int    mage=22; @Overridepublic String toString() {return "ReflectionTest [mName=" + mName + ", mage=" + mage + "]";}//无参数构造函数public ReflectionTest() {// TODO Auto-generated constructor stub}//带参数的构造函数public ReflectionTest(String name ,int age) {this.mName=name;this.mage=age;}//无参数的方法protected  void getReflection(){Log.e("hjo", "这是调用无参无返回函数getReflection 而被打印输出的!");}//有参数有返回的方法public String StringMethods(String str ,int age){return str + "    " + age;}


    1.三种通过反射获取类的方式

public void getClassWay(){//通过getClass获取一个类String str="str";Class classone =str.getClass();Log.e("hjo", "getClass 方式获取:"+classone.toString());//通过.class 获取Class classtwo=ReflectionTest.class;Log.e("hjo", ".class 方式获取:"+classtwo.toString());//通过静态方式获取 也是平时使用最多的一种   需要加载异常机制Class classthree = Class.forName("com.hjo.reflectiondemo.ReflectionTest");Log.e("hjo", "静态获取方式   :"+classthree.toString());}
    

运行结果:
  

2.获取类里面的方法和属性

public void fristMethods(){ //通过反射机制,使用类装载器,装载该类  Class classone=Class.forName("com.hjo.reflectiondemo.ReflectionTest");//注意 这里是完整的类名 即包名加类名Object object=classone.newInstance();//调用其无参构造函数//获取其所有的方法Method []methods=classone.getDeclaredMethods();for (Method method : methods) {Log.e("hjo", "ReflectionTest 类中的方法   :"+method);}Field []fields=classone.getDeclaredFields();for (Field field : fields) {Log.e("hjo", "ReflectionTest 类中的属性   :"+field);Log.e("hjo", "field属性的类型   :"+field.getType().getSimpleName());}}

运行结果:



3. 属性的调用

public void SecondMethods(){Class classone=Class.forName("com.hjo.reflectiondemo.ReflectionTest");/******通过无参构造函数进行实例化********/Object object1=classone.newInstance();//使用无参构造函数实例化//调用属性Field field=classone.getDeclaredField("mName");//获取mName属性field.setAccessible(true);//正面肛  暴力打破封装  造成属性不安全field.set(object1, "那啥,这是从新给mName这个属性修改的字符串!");Log.e("hjo", "object1:"+field.get(object1));}
运行结果:



4.调用放方法

 注意  在这里如果方法的修饰符是私有的  则无法反射到   只有是protected和 public方可进行反射和进行调用  所有在一些较为重要的或不宜暴露的方法可设置为private

public void ThreeMethods(){Class classone=Class.forName("com.hjo.reflectiondemo.ReflectionTest");/******通过无参构造函数进行实例化********/Object object1=classone.newInstance();//使用无参构造函数实例化//调用有返回类型 有参数的方法 StringMethods//第一个参数为方法名  第二个参数是一个数组形式传入参数的类型   如new class[]{int.class ,String.class};Method method2=classone.getDeclaredMethod("StringMethods", new Class[]{String.class,int.class});//object2为返回的字符串  //第一个参数为实例化的对象  第二个参数为数组  传入值如Object []{23,"PSS"};Object object2=method2.invoke(object1, new Object[]{"隔壁李翠花",23}); Log.e("hjo", "这是调用有参数有返回的方法StringMethods的得到的返回字符串:"+object2.toString() );/*******调用方法*********///调用无返回类型的Method method1=classone.getDeclaredMethod("getReflection");method1.invoke(object1); }

运行结果:


5.实例化方式
public void FoutMethods(){/*********调用无参构造函数进行实例化********/Class classone = Class.forName("com.hjo.reflectiondemo.ReflectionTest");Object object1=classone.newInstance();//使用无参构造函数实例化Log.e("hjo", "通过无参构造函数进行实例化:"+object1.toString());//这里之所以在不确定该类的情况下可进行调用是因为toString这个类本身就是Object类里的方法  而所有类的又是继承自Object的/*****调用有参数的构造函数实例化***///获取无参构造器  //        Constructor<?> constructor1 = classone.getDeclaredConstructor();          //获取有参构造器,根据参数类型匹配          Constructor<?> constructor2 = classone.getDeclaredConstructor(String.class, int.class); Object object2=constructor2.newInstance("大兄弟",25);Log.e("hjo", "通过有参构造函数进行实例化:"+object2.toString());}
   当无法得知该类中的构造参数类型时可使用以下方式进行打印输出:

/********以下方式可输出一个类的所有构造函数和对应构造函数的参数类型 Constructor ctorlist[] = classone.getDeclaredConstructors(); //获取该类的所有构造函数      for (int i = 0; i < ctorlist.length; i++) {       Constructor ct = ctorlist[i];        Class canshuType[] = ct.getParameterTypes();        for (int j = 0; j < canshuType.length; j++) //输出它的构造的参数类型       Log.e("hjo", "参数类型为" + j + " " + canshuType[j]);      } **********/
 运行结果:




完整的代码如下:

package com.hjo.reflectiondemo;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import android.os.Bundle;import android.app.Activity;import android.util.Log;import android.view.Menu;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//getClassWay();//fristMethods();//SecondMethods();//ThreeMethods();FoutMethods();}//实例化方式public void FoutMethods(){try {/*********调用无参构造函数进行实例化********/Class classone = Class.forName("com.hjo.reflectiondemo.ReflectionTest");Object object1=classone.newInstance();//使用无参构造函数实例化Log.e("hjo", "通过无参构造函数进行实例化:"+object1.toString());//这里之所以在不确定该类的情况下可进行调用是因为toString这个类本身就是Object类里的方法  而所有类的又是继承自Object的/*****调用有参数的构造函数实例化***//********以下方式可输出一个类的所有构造函数和对应构造函数的参数类型 Constructor ctorlist[] = classone.getDeclaredConstructors(); //获取该类的所有构造函数      for (int i = 0; i < ctorlist.length; i++) {       Constructor ct = ctorlist[i];        Class canshuType[] = ct.getParameterTypes();        for (int j = 0; j < canshuType.length; j++) //输出它的构造的参数类型       Log.e("hjo", "参数类型为" + j + " " + canshuType[j]);      } **********///获取无参构造器  //        Constructor<?> constructor1 = classone.getDeclaredConstructor();          //获取有参构造器,根据参数类型匹配          Constructor<?> constructor2 = classone.getDeclaredConstructor(String.class, int.class); Object object2=constructor2.newInstance("大兄弟",25);Log.e("hjo", "通过有参构造函数进行实例化:"+object2.toString());} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InstantiationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalArgumentException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InvocationTargetException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (NoSuchMethodException e) {// TODO Auto-generated catch blocke.printStackTrace();}}//调用方法   注意  在这里如果方法的修饰符是私有的  则无法反射到   只有是protected和 public方可进行反射和进行调用  所有在一些较为重要的或不宜暴露的方法可设置为privatepublic void ThreeMethods(){try {Class classone=Class.forName("com.hjo.reflectiondemo.ReflectionTest");/******通过无参构造函数进行实例化********/Object object1=classone.newInstance();//使用无参构造函数实例化//调用有返回类型 有参数的方法 StringMethods//第一个参数为方法名  第二个参数是一个数组形式传入参数的类型   如new class[]{int.class ,String.class};Method method2=classone.getDeclaredMethod("StringMethods", new Class[]{String.class,int.class});//object2为返回的字符串  //第一个参数为实例化的对象  第二个参数为数组  传入值如Object []{23,"PSS"};Object object2=method2.invoke(object1, new Object[]{"隔壁李翠花",23}); Log.e("hjo", "这是调用有参数有返回的方法StringMethods的得到的返回字符串:"+object2.toString() );/*******调用方法*********///调用无返回类型的Method method1=classone.getDeclaredMethod("getReflection");method1.invoke(object1); } catch (ClassNotFoundException e) {//没有该反射类时抛出// TODO Auto-generated catch blocke.printStackTrace();} catch (InstantiationException e) {//没有该构造方式时平抛出// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();}  catch (NoSuchMethodException e) {//无该方法时调用// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalArgumentException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InvocationTargetException e) {// TODO Auto-generated catch blocke.printStackTrace();}}//调用属性  属性的修饰符可以是任何一种  public void SecondMethods(){try {Class classone=Class.forName("com.hjo.reflectiondemo.ReflectionTest");/******通过无参构造函数进行实例化********/Object object1=classone.newInstance();//使用无参构造函数实例化//调用属性Field field=classone.getDeclaredField("mName");//获取mName属性field.setAccessible(true);//正面肛  暴力打破封装  造成属性不安全field.set(object1, "那啥,这是从新给mName这个属性修改的字符串!");Log.e("hjo", "object1:"+field.get(object1));} catch (ClassNotFoundException e) {//没有该反射类时抛出// TODO Auto-generated catch blocke.printStackTrace();} catch (InstantiationException e) {//没有该构造方式时平抛出// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (NoSuchFieldException e) {//无该属性时抛出// TODO Auto-generated catch blocke.printStackTrace();}}//获取类里面的方法和属性public void fristMethods(){try { //通过反射机制,使用类装载器,装载该类  Class classone=Class.forName("com.hjo.reflectiondemo.ReflectionTest");//注意 这里是完整的类名 即包名加类名Object object=classone.newInstance();//调用其无参构造函数//获取其所有的方法Method []methods=classone.getDeclaredMethods();for (Method method : methods) {Log.e("hjo", "ReflectionTest 类中的方法   :"+method);}Field []fields=classone.getDeclaredFields();for (Field field : fields) {Log.e("hjo", "ReflectionTest 类中的属性   :"+field);Log.e("hjo", "field属性的类型   :"+field.getType().getSimpleName());}} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InstantiationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();}}//三种通过反射获取类的方式public void getClassWay(){//通过getClass获取一个类String str="str";Class classone =str.getClass();Log.e("hjo", "getClass 方式获取:"+classone.toString());//通过.class 获取Class classtwo=ReflectionTest.class;Log.e("hjo", ".class 方式获取:"+classtwo.toString());//通过静态方式获取 也是平时使用最多的一种   需要加载异常机制try {Class classthree = Class.forName("com.hjo.reflectiondemo.ReflectionTest");Log.e("hjo", "静态获取方式   :"+classthree.toString());} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}//注意 这里一定是hi完整的类名 即包名加类名}}


   





    

0 0