java的反射机制笔记

java的反射机制笔记
首先了解什么是反射机制
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的 所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
JAVA反射(放射)机制:“程序运行时,允许改变程序结构或变量类型,这种语言称为 动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。
通过以上的信息,我们可以猜测下,我们平时所做的应用所接的第三方的sdk,经常会让我们在自己的报名下放置相关的java类,可以添加自己的逻辑,这边应该也是用到了反射的机制,下面一起探索吧^_^,看看反射机制的作用。
这边有篇写的关于import语句的文章,写的不错 http://zhaohe162.blog.163.com/blog/static/3821679720101120104444895/
1.相关操作定义

方法名

含义

getDeclaredFields()

获取类包含的全部变量,返回Field[]

getDeclaredFields(String name)

获取传入制定的的变量名的变量Field

getDeclaredMethods()

获取当前类的所有方法method[]

getDeclaredMethod(String name )

获取当前的name的方法

getDeclaredMethod(String name ,class[] …)

获取当前的name和参数class的方法

getReturnType()

获取方法的返回值类型

getParameterTypes()

获取方法的出入参数

getDeclaredConstructors()

获取当前类的构造方法

getDeclaredConstructor(class[],…)

获取带参数的构造方法

getSuperclass()

获取父类

getInterfaces()

获取当前类实现的接口











2.实现获取类的相关变量
先定义一个非常简单的Utils类
public class Utils {
    public static String a = "a";
    private String b = "b";
    protected boolean c = false;

    public String getA(){
        Log.i("lz","lz do getA =" + a);
        return a;
    }
    public static  String getAS(){
        Log.i("lz","lz do getAS =" + a);
        return a;
    }
    private String getB(){
        Log.i("lz","lz do getB =" + b);
        return b;
    }
    public boolean getC(){
        Log.i("lz","lz do getC =" + c);
        return c;
    }
    public void printA(){
        Log.i("lz","lz do printA a=" + a);
    }
    public void printAB(int a){
        Log.i("lz","lz do printA a=" + a);
    }
}
获取Utils类中的所有变量
    //get all fields by class
    public static StringBuffer getAllFields(){
        StringBuffer sb = new StringBuffer();
        try {
            //第一种
//            Class c = Class.forName("类的目录.Utils");
            //第二种
            Class c = l.loadClass("类的目录.Utils");
            Object o = c.newInstance();
            Field d[] = c.getDeclaredFields();
            sb.append(Modifier.toString(c.getModifiers()) + " class " + c.getSimpleName() + "\n");
            for (Field f:d) {
                f.getName();
                sb.append("\t");//空格
                sb.append(Modifier.toString(f.getModifiers())+" ");//获得属性的修饰符,例如public,static等等
                sb.append(f.getType().getSimpleName() + " ");//属性的类型的名字
                sb.append(f.getName()+";\n");//属性的名字+回车
            }
            Log.i("lz","lz do info class=" + sb);
            return sb;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            Log.i("lz","lz do class 11111111111111111");
        } catch (InstantiationException e) {
            e.printStackTrace();
            Log.i("lz","lz do class 22222222222222222");
        } catch (IllegalAccessException e) {
            Log.i("lz","lz do class 333333333333333333");
            e.printStackTrace();
        }
        return sb;
    }

      获取制定名字的变量并且赋值
   //set reflect field by give field name
    public static String getFieldByName(String name){
        Class c = null;
        try {
            c = l.loadClass("累的目录.Utils");
            Object o = c.newInstance();
            Field f = c.getDeclaredField(name);
            //打破封装
            f.setAccessible(true); //使用反射机制可以打破封装性,导致了java对象的属性不安全。
            f.set(o,"set do");//设置name的变量的值是set do字符串
            return ((Utils)o).getA();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        return "";
    }

获取所有的方法
 public static String getAllMethods(){
        Class c = null;
        StringBuffer sb = new StringBuffer();
        try {
            c = l.loadClass("类的目录.Utils");
            Method m[] = c.getDeclaredMethods();
            for (Method me:m) {
                sb.append(Modifier.toString(me.getModifiers()) + " " + me.getName()
                       + " " + me.getReturnType() + "\n");
                for (Class cl:me.getParameterTypes()) {
                    sb.append("\t" + cl.getName() + "\n");
                }
            }
            return sb.toString();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return "";
    }

    获取指定的方法
  public static void doMethodByGiveParams(String methName,Class params[],@android.support.annotation.Nullable Object args[]){
        Class c = null;
        try {
            c = l.loadClass("类的目录.Utils");
            Method m = c.getMethod(methName,params);
            //出入参数,执行指定的方法,如果有返回值,返回o,方法无参数,args不传 //m.invoke(c)
            Object o = m.invoke(c,args);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

细心的朋友可能已经注意到加载类的两个不同的方法,下面讲述Class.forname 和ClassLoader.loadClass的区别,稍后敬上... ...












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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值