• java反射机制的进一步理解


    承上一篇。

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
    Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

    java反射机制的存在让你只要知道类名就能生成这个类的实例。如果这么说的话,那岂不是违反了java做为面向对象语言的封装性,而且更恐怖的是你还可以得到这个类的属性(public)。但是其实反射机制的存在并不破坏封装新,它虽然可以生成任何类的实例,但是在当前你所在的类,如果想要生成某个类,这个类必须是当前类可见的,那么这个类必须是当前类的成员之一;它虽然能得到属性的值但所得的属性值本身就是public,所以不能说是破坏了封装性。

    例子:

    public class WTAimObject {
    
    	public String name = "Jobs";
    	
    	public String getName(){
    		return name;
    	}
    }
    

      

     1 public class WTGetField {
     2 
     3     public static Object getProperty(Object owner, String fieldName) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException{
     4         Class ownerClass = owner.getClass();
     5         
     6         Field field = ownerClass.getField(fieldName);
     7         
     8         System.out.println(field.toString());
     9         
    10         System.out.println(field.getName());
    11         
    12         Object     property = field.get(owner);
    13         return property;
    14     }
    15     
    16     public static void main(String args[]) throws SecurityException, IllegalArgumentException, NoSuchFieldException, IllegalAccessException{
    17         WTAimObject aimObject = new WTAimObject();
    18         
    19         System.out.println(WTGetField.getProperty(aimObject, "name").toString());
    20     }
    21 }

    这个输出结果就是

    public java.lang.String WTAimObject.name
    name
    Jobs

    所以课件字段的意思:包含属性名,属性所属类,属性的public,private等;这里注意:如果这个属性是private在field.get(owner)时,会报错,但在field.name()不会。即不能通过field.get(owner);生成实例并获得值。

    另一个需要注意的是:执行某个对象的方法,这也是动态代理能实现的基础!


    这有一个超级好的例子我就直接搬来啦:

    public Object invokeMethod(Object owner, String methodName, Object[] args) throws Exception {
     
         Class ownerClass = owner.getClass();
     
         Class[] argsClass = new Class[args.length];
     
         for (int i = 0, j = args.length; i < j; i++) {
             argsClass[i] = args[i].getClass();
         }
    
          Method method = ownerClass.getMethod(methodName,argsClass);
     
         return method.invoke(owner, args);
    }
    

    Class owner_class = owner.getClass() :首先还是必须得到这个对象的Class。

    5~9行:配置参数的Class数组,作为寻找Method的条件。

    Method method = ownerClass.getMethod(methodName, argsClass):通过methodName和参数的argsClass(方法中的参数类型集合)数组得到要执行的Method。

    method.invoke(owner, args):执行该Method.invoke方法的参数是执行这个方法的对象owner,和参数数组args,可以这么理解:owner对象中带有参数args的method方法。返回值是Object,也既是该方法的返回值。

    这个当中我们可以发现,当我们处理到一个类的定义时,所有的操作都是对这个类的class进行的操作的,这个Class对象是由JVM在运行时创建的,不支持现实和构造,虚拟机为每个类型创建一个读一无二的Class。一般JVM遇到显示新建一个类对象,那么JVM一般会检查是否已经加载该类的Class,如果已经加载就会使用这个Class生成该类的所有对象。

    参考Class类 的解释:http://lavasoft.blog.51cto.com/62575/15433/  这个很详细 。

    反射机制参考:http://azrael6619.iteye.com/blog/429797

  • 相关阅读:
    C# 根据Word模版生成Word文件
    C# 添加事件
    类HTML语法显示格式化文本
    简易内存池实现
    12306订票助手
    网站前端的收藏
    摘抄 ander图片上传
    对于文件上传的几种处理方法,转载的
    对于 asp.net 中IhttpHandle,和IHttpModel中使用Session 会话
    KindEdit 的编辑插件的提问家
  • 原文地址:https://www.cnblogs.com/chaiwentao/p/4401423.html
Copyright © 2020-2023  润新知