一:反射机制
反射是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());
}
}
运行结果:
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);
}
运行结果:
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完整的类名 即包名加类名
}
}