反射机制的使用

   一:反射机制

         反射是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; 
	
	@Override
	public 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 {
	@Override
	protected 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 block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	

	//调用方法   注意  在这里如果方法的修饰符是私有的  则无法反射到   只有是protected和 public方可进行反射和进行调用  所有在一些较为重要的或不宜暴露的方法可设置为private
	public 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 block
			e.printStackTrace();
		} catch (InstantiationException e) {//没有该构造方式时平抛出
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}  catch (NoSuchMethodException e) {//无该方法时调用
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.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 block
			e.printStackTrace();
		} catch (InstantiationException e) {//没有该构造方式时平抛出
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchFieldException e) {//无该属性时抛出
			// TODO Auto-generated catch block
			e.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 block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.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 block
				e.printStackTrace();
			}//注意 这里一定是hi完整的类名 即包名加类名
		}

}



   





    

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值