《Java反射的应用》

《Java反射的应用》

最近在研究Java并发相关的类库,看到了AtomicIntegerFieldUpdater,这个类就是利用反射来完成原子更新字段的值。由于自己对反射相关的操作都忘记了,今天刚好借此机会就看了下API文档温习了一下。也写了一个小例子。

例子中基本上涵盖了我们利用反射来获取类的属性、方法、构造函数等应用。

例子完成的功能:首先有一个Student类,然后我们利用反射机制获取类相关的属性和方法组合为一个字符串打印输出,最后我们利用反射获取某个指定属性和某个指定方法对其使用使用。

    public class TestClass {
        private static Class c = null;
        public static void main(String[] args) throws Exception {

            try {
                //获取类
                 c = Class.forName("com.wrh.atomic.Student");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }

            String classContentStr = getClassInformation();
            System.out.println(classContentStr);

            //对属性的使用
            Field fId = c.getDeclaredField("id");//不能使用c.getField("id");因为getField只能返回公共属性
            fId.setAccessible(true);//使用反射机制可以打破封装性,导致了java对象的属性不安全。
            Object obj = c.newInstance();
            fId.set(obj, 10);
            //System.out.println(fId.get(obj));
            //调用方法
            Method m =c.getDeclaredMethod("getId");
            m.invoke(obj);
            Method m2 = c.getDeclaredMethod("setId", int.class);
            m2.invoke(obj, 4);

        }
        private static String getClassInformation() {
            StringBuffer sb = new StringBuffer();
            sb.append(Modifier.toString(c.getModifiers())).append("class ").append(c.getSimpleName()).append(" {\n");

            //获取所有的属性
            Field[] fields = c.getDeclaredFields();
            //获取属性的修饰符、类型和名字
            for(Field f:fields){
                sb.append("\t");//空格
                sb.append(Modifier.toString(f.getModifiers())+" ");//属性的修饰符
                sb.append(f.getType().getSimpleName()+" ");//属性类型的名字
                sb.append(f.getName()).append(";\n");//属性的名字
            }

            //获取所有的方法
            Method[] methods = c.getDeclaredMethods();

            for(Method m:methods){
                sb.append("\t");//空格
                sb.append(Modifier.toString(m.getModifiers())+" ");//修饰符
                sb.append(m.getReturnType().getSimpleName()+" ");//返回值类型
                sb.append(m.getName());//方法的名字
                Class[] parameters=m.getParameterTypes(); //获得方法传入参数的类型
                StringBuffer sbPara = new StringBuffer();
                if(parameters.length!=0){
                    for(Class p:parameters){
                        sbPara.append(p.getSimpleName()+",");
                    }
                    sb.append("("+sbPara.substring(0,sbPara.length()-1)+")");
                }
                else{
                    sb.append("()");
                }
                sb.append("{\n");//添加换行符
                sb.append("\t}\n");//添加方法的右大括号

            }
            sb.append("}");

            return sb.toString();
        }

    }

    class Student{
        private int id;
        private String name;
        private int age;
        public int getId() {
            System.out.println("get id :"+id);
            return id;
        }
        public void setId(int id) {
            System.out.println("set id :"+id);
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }

    }

关于反射更多的介绍请参考API文档。下面也贴出两篇比较好的反射博客

1、http://blog.csdn.net/liujiahan629629/article/details/18013523

2、http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html

可能我们有时候会有这样的问题,反射机制中可以获取private成员的值吗(没有set和get函数)

对于这样的问题,我们只有实验,我们才能知道,如下:

package com.wrh.atomic;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class TestClass2 {
    private static Class c = null;
    public static void main(String[] args) throws Exception {
        Student2 s = new Student2(2,"haohao",22);

        c = s.getClass();
        //对属性的使用
        Field fId = c.getDeclaredField("id");//不能使用c.getField("id");因为getField只能返回公共属性
        fId.setAccessible(true);//使用反射机制可以打破封装性,导致了java对象的属性不安全。

        int id =(int)fId.get(s);
        System.out.println(id);
    }

}

class Student2{
    private int id;
    private String name;
    private int age;
    public Student2(int id,String name,int age){
        this.id = id;
        this.name = name;
        this.age = age;
    }
}

输出结果为:2

结论:是可以利用反射来获取private的属性(没有set和get方法)的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值