概念


反射是在类加载时,不知道具体要加载什么东西,而在运行时,就知道了要加载的东西,从而回过头去加载的过程

反射也是创建对象的一种方式

例子


  1. public static void main(String[] args) {
  2. // TODO Auto-generated method stub
  3. //从properties文件中读取字符串,该字符串是girl子类的包路径
  4. String girl = PropertiesUtil.getValue("girl");
  5. System.out.println(girl);
  6. //用反射
  7. try {
  8. //forName() 调用 类加载器 去重新加载
  9. Class cls = Class.forName(girl);
  10. System.out.println(cls);
  11. System.out.println(cls.newInstance());
  12. } catch (Exception e) {
  13. // TODO Auto-generated catch block
  14. e.printStackTrace();
  15. }
  16. }

反射中,最核心的方法:Class.forName()
Class.forName() 可以做到:在运行期去加载 需要的类

Class类


如果你在程序代码,需要使用到Class类,有3种方式获取:
1、Class.forName() 应用于反射
2、如果已知类的情况,使用类名.class 也可以获取到
3、如果已知类的对象,使用 对象.getClass() 同样可以获取到

使用Class类创建对象,调用方法,调用属性


创建对象

调用无参构造

                         //forName() 调用 类加载器 去重新加载
            Class cls = Class.forName(girl);
            //根据cls创建实例 newInstance() 调用无参构造器
            Object obj = cls.newInstance();

调用有参构造

                        //forName() 调用 类加载器 去重新加载
            Class cls = Class.forName(girl);
            //返回有参构造器
            Constructor cons = cls.getConstructor(String.class,Integer.class);
            Object obj = cons.newInstance("三上",18);
            System.out.println(obj);

调用属性

            //返回有参构造器
            Constructor cons = cls.getConstructor(String.class,Integer.class);
            Object obj = cons.newInstance("三上",18);
            System.out.println(obj);
                    //不能返回私有属性
                    Field field = cls.getField("girlName");
                    System.out.println(field.get(obj));
            //可以返回 私有属性
            Field field = cls.getDeclaredField("girlName");
            //给其他类,授权访问 私有属性
            field.setAccessible(true);
            System.out.println(field.get(obj));
            //set 主要给属性赋新的值
            field.set(obj, "市川**");
            //get 主要用于获得属性的内容
            System.out.println(field.get(obj));

调用方法

            //获取私有方法
            Method meth = cls.getDeclaredMethod("cry", null);
            meth.setAccessible(true);//同样给私有方法,授权
            System.out.println(meth);
            //调用方法(第一个参数表示对象,第二个参数表示 具体的值)
            Object result = meth.invoke(obj, null);
            //输出方法的返回结果
            System.out.println(result);
            //获得非私有方法(第一个参数表示方法名,第二个参数表示 参数类型)
//            Method meth = cls.getMethod("cry", null);
//            System.out.println(meth);
//            //调用方法(第一个参数表示对象,第二个参数表示 具体的值)
//            Object result = meth.invoke(obj, null);
//            //输出方法的返回结果
//            System.out.println(result);

获得注解

                         //返回有参构造器
            Constructor cons = cls.getConstructor(String.class,Integer.class);
            Object obj = cons.newInstance("三上",18);
            System.out.println(obj);
            //根据方法对象,获得方法上的 注解
            Method meth = cls.getMethod("cry", null);
            MyLog mylog = meth.getAnnotation(MyLog.class);
            System.out.println(mylog.menuName());
            System.out.println(mylog.optType());