`
Cwind
  • 浏览: 262944 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
博客专栏
793bb7df-a2a9-312d-8cb8-b66c3af482d1
LeetCode题解
浏览量:52481
社区版块
存档分类
最新评论

从Introspector谈Java内省机制

    博客分类:
  • Java
阅读更多
内省
内省是Java语言的一种重要特性。使用内省我们可以在运行时得到一个类的内部信息。这些信息包括方法、属性、构造函数及其他。内省的一个应用是开发使用插件的应用程序。应用程序可以在运行时获取并使用插件类的构造函数、方法和属性。内省也可以应用于创建Java Beans和Javadocs中。
Introspector类
Introspector类为访问目标Jave Bean支持的属性、事件和方法提供了标准方法。该方法可用于工具类(如BeanUtils)中。
对于属性、事件和方法中的每一类信息,Introspector会分别分析目标bean以及其父类,寻找显式或隐式信息并用其构建一个能够全面描述目标bean的BeanInfo对象。
通过调用Introspector.getBeanInfo()方法来获得指定类的bean信息。Java Bean规范允许通过实现BeanInfo接口,定义一个对象来描述bean。为了将BeanInfo与bean关联起来,须遵守如下命名模式:bean信息类的名字必须是将"BeanInfo"添加到bean名字的后面构成。例如:
package com.cwind.introspector;

public class Ultraman extends Superhero {
        public String avanta ;

        public Ultraman(String avanta) {
               super ();
               this .avanta = avanta;
       }

        public String getAvanta() {
               return avanta ;
       }

        public void setAvanta(String avanta) {
               this .avanta = avanta;
       }
}
 相关信息类:
package com.cwind.introspector;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.beans.SimpleBeanInfo;

public class UltramanBeanInfo extends SimpleBeanInfo {
        public PropertyDescriptor[] getPropertyDescriptors() {
               try {
                      return new PropertyDescriptor[]{
                            new PropertyDescriptor("avanta" , Ultraman. class),
                            new PropertyDescriptor("name" , Ultraman. class)
                     };
              } catch (IntrospectionException e) {
                     e.printStackTrace();
                      return null ;
              }
       }
}
信息类会先从Bean类所在的包内查找,如上例中搜索路径为com.cwind.introspector.UltramanBeanInfo。搜索路径也可以通过Introspector.setBeanInfoSearchPath()进行设置。使用BeanInfo类是为了获取对bean属性的控制权。只需提供属性名和所属的bean类,就可以为每个属性构建一个PropertyDescriptor。
演示类Superhero及其另一子类Titan定义:
package com.cwind.introspector;

public class Superhero {
     private String name ;
     private String superPower ;
     private int age ;
       
     public Superhero(){
          this.name = "defaultName" ;
          this.superPower  = "defaultSuperPower" ;
          this.age = 0;
     }
       
     public Superhero(String name, String superPower, int age) {
          super();
          this.name = name;
          this.superPower = superPower;
          this.age = age;
     }

     public String getName() {
          return name ;
     }
     public void setName(String name) {
          this.name = name;
     }
     public String getSuperPower() {
          return superPower ;
     }
     public void setSuperPower(String superPower) {
          this.superPower = superPower;
     }
     public int getAge() {
          return age ;
     }
     public void setAge(int age) {
          this.age = age;
     }
}

package com.cwind.introspector;

public class Titan extends Superhero {
     private double height ;
     private double weight ;
       
     public Titan(double height, double weight) {
          super();
          this.height = height;
          this.weight = weight;
     }
       
     public double getHeight() {
          return height ;
     }
     public void setHeight(double height) {
          this.height = height;
     }
     public double getWeight() {
          return weight ;
     }
     public void setWeight(double weight) {
          this.weight = weight;
     }  
}
 
可以看到,Ultraman类有一个显式的BeanInfo类,其中的属性描述符仅包括"avanta"和继承自父类的"name"。Titan没有显式的BeanInfo类。下面用一个测试类来打印Introspector获取的BeanInfo信息,分别打印两个Ultraman和Titan实例的属性名称及其对应的值,比较其异同。
package com.cwind.introspector;

import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;

public class IntrospectorTest {
     public static void main(String[] args) throws IntrospectionException, IllegalArgumentException, IllegalAccessException, InvocationTargetException{
          PropertyDescriptor[] ultramanProps = Introspector.getBeanInfo(Ultraman.class).getPropertyDescriptors();
          Ultraman sailor = new Ultraman("sailor" );
          for(PropertyDescriptor prop : ultramanProps){
               System. out.println("Property name: " + prop.getName()+ ", value: "+ prop.getReadMethod().invoke(sailor, null));
          }
          System. out.println();
          PropertyDescriptor[] titanProps = Introspector.getBeanInfo(Titan.class).getPropertyDescriptors();
          Titan titan = new Titan(999,888);
          for(PropertyDescriptor prop : titanProps){
               System. out.println("Property name: " + prop.getName()+ ", value: "+ prop.getReadMethod().invoke(titan, null));
          }
     }
}
 
输出结果如下:
Property name: avanta, value: sailor
Property name: name, value: defaultName

Property name: age, value: 0
Property name: class, value: class com.cwind.introspector.Titan
Property name: height, value: 999.0
Property name: name, value: defaultName
Property name: superPower, value: defaultSuperPower
Property name: weight, value: 888.0
 
可以看到,对于前者,只打印出其显式BeanInfo类中返回的属性描述符所对应的属性;对于后者,使用低层次的反射来获取所有属性,并按照属性名称字母序将属性描述符数组返回。
为了更好的性能,Introspector缓存BeanInfo;因此,若在使用多个类加载器的应用程序中使用Introspector须小心谨慎。可以调用Introspector.flushCaches或Introspector.flushFromCaches方法从缓存中清空内省的类。
Reference:
6. Java2核心技术 卷II:高级特性,第8章:JavaBean构件;【美】Cay S. Horstmann, Gary Cornell 著;机械工业出版社
  • 大小: 47.8 KB
2
5
分享到:
评论

相关推荐

    JAVA的内省机制(introspector)与反射机制(reflection).docx

    JAVA的内省机制(introspector)与反射机制(reflection).docx

    Java 内省(Introspector)深入理解

    主要介绍了Java 内省(Introspector)深入理解的相关资料,需要的朋友可以参考下

    Java 内省introspector相关原理代码解析

    主要介绍了Java 内省introspector相关原理代码解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    java-beans-lite:轻量级且快速的java.beans.Introspector实现

    由于它与AWT的紧密依赖,因此无法轻易将其从java.desktop模块中删除,从而导致任何使用java.beans包的第三方库都依赖于所有java.desktop类,从而在JVM安装中增加了12mb的额外开销,并且一些额外的内存使用情况。...

    java 编程入门思考

    13.18.2 用Introspector提取BeanInfo 13.18.3 一个更复杂的Bean 13.18.4 Bean的封装 13.18.5 更复杂的Bean支持 13.18.6 Bean更多的知识 13.19 Swing入门 13.19.1 Swing有哪些优点 13.19.2 方便的转换 13.19.3 显示...

    Java初学者入门教学

    13.18.2 用Introspector提取BeanInfo 13.18.3 一个更复杂的Bean 13.18.4 Bean的封装 13.18.5 更复杂的Bean支持 13.18.6 Bean更多的知识 13.19 Swing入门 13.19.1 Swing有哪些优点 13.19.2 方便的转换 13.19.3 显示...

    java联想(中文)

    13.18.2 用Introspector提取BeanInfo 13.18.3 一个更复杂的Bean 13.18.4 Bean的封装 13.18.5 更复杂的Bean支持 13.18.6 Bean更多的知识 13.19 Swing入门 13.19.1 Swing有哪些优点 13.19.2 方便的转换 13.19.3 显示...

    JAVA_Thinking in Java

    13.18.2 用Introspector提取BeanInfo 13.18.3 一个更复杂的Bean 13.18.4 Bean的封装 13.18.5 更复杂的Bean支持 13.18.6 Bean更多的知识 13.19 Swing入门 13.19.1 Swing有哪些优点 13.19.2 方便的转换 13.19.3 显示...

    Thinking in Java 中文第四版+习题答案

    13.18.2 用Introspector提取 13.18.3 一个更复杂的 13.18.4 Bean的封装 13.18.5 更复杂的Bean支持 13.18.6 Bean更多的知识 13.19 Swing入门 13.19.1 Swing有哪些优点 13.19.2 方便的转换 13.19.3 显示框架 13.19.4 ...

    Thinking in Java简体中文(全)

    13.18.2 用Introspector提取BeanInfo 13.18.3 一个更复杂的Bean 13.18.4 Bean的封装 13.18.5 更复杂的Bean支持 13.18.6 Bean更多的知识 13.19 Swing入门 13.19.1 Swing有哪些优点 13.19.2 方便的转换 13.19.3 显示...

    JAVA_Thinking in Java(中文版 由yyc,spirit整理).chm

    JAVA_Thinking in Java(中文版 由yyc,spirit整理).chm ------------------------------------------------- 本教程由yyc,spirit整理 ------------------------------------------------- “Thinking in Java...

    Neo4j GraphQL 库(graphql--neo4j-introspector-1.0.1.zip)

    Neo4j GraphQL 库(graphql--neo4j-introspector-1.0.1.zip) 源代码。 Neo4j GraphQL 库是一个高度灵活、低代码、开源的 JavaScript 库,可通过利用连接数据的力量为跨平台和移动应用程序实现快速 API 开发。 ...

    php-introspector

    这个包是一个薄包装器,它从内省中检索建议: 安装 使用 Atom 包管理器,它可以在设置视图中找到,或者从命令行运行apm install php-introspector 。 您还需要安装软件包。 用法 目前,自动完成依赖于从远程(或...

    openbeans1.0.zip

    //import java.beans.Introspector; //import java.beans.PropertyDescriptor; import com.googlecode.openbeans.BeanInfo; import com.googlecode.openbeans.IntrospectionException; import ...

    Neo4j GraphQL 库(graphql--neo4j-introspector-1.0.1.tar.gz)

    Neo4j GraphQL 库(graphql--neo4j-introspector-1.0.1.tar.gz) 源代码。 Neo4j GraphQL 库是一个高度灵活、低代码、开源的 JavaScript 库,可通过利用连接数据的力量为跨平台和移动应用程序实现快速 API 开发。 ...

    Python库 | plone.introspector-0.1.tar.gz

    资源分类:Python库 所属语言:Python 资源全名:plone.introspector-0.1.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    Java基础加强(上) 经典ppt

    讲一些经典的:静态导入 自动装箱/拆箱 增强for循环 可变参数 内省(Introspector) — JavaBean ......

    Think in Java(中文版)chm格式

    13.18.2 用Introspector提取BeanInfo 13.18.3 一个更复杂的Bean 13.18.4 Bean的封装 13.18.5 更复杂的Bean支持 13.18.6 Bean更多的知识 13.19 Swing入门 13.19.1 Swing有哪些优点 13.19.2 方便的转换 13.19....

    使用struts2的Introspector做日志

    NULL 博文链接:https://liuna718-163-com.iteye.com/blog/1731217

    Thinking in Java(中文版 由yyc,spirit整理).chm

    13.18.2 用Introspector提取BeanInfo 13.18.3 一个更复杂的Bean 13.18.4 Bean的封装 13.18.5 更复杂的Bean支持 13.18.6 Bean更多的知识 13.19 Swing入门 13.19.1 Swing有哪些优点 13.19.2 方便的转换 13.19.3 显示...

Global site tag (gtag.js) - Google Analytics