java 解析省或直辖市 java内省的作用 您所在的位置:网站首页 内省的作用是 java 解析省或直辖市 java内省的作用

java 解析省或直辖市 java内省的作用

2024-05-07 22:40| 来源: 网络整理| 查看: 265

  为什么要学内省?

         开发框架时,经常需要使用 java 对象的属性来封装程序的数据,每次都使用反射技术完成此类操作过于麻烦,所以 sun 公司开发了一套 API ,专门用于操作 java 对象的属性。

  什么是 Java 对象的属性和属性的读写方法 ?

  内省访问 JavaBean 属性的两种方式:

         通过 PropertyDescriptor 类操作 Bean 的属性;

         通过 Introspector 类获得 Bean 对象的 BeanInfo ,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后通过反射机制来调用这些方法。

¨   内省是 Java 语言对 Bean 类属性 的一种缺省处理方法。例如类 A 中有属性 name, 可以通过 getName,setName 来得到其值或者设置新的值。通过 getName / setName 来访问 name 属性,这是默认的规则。 Java 中提供了一套 API 来访问某个属性的 getter/setter 方法。

   ¨ 一般的做法是通过类 Introspector 来获取某个对象的 BeanInfo 信息,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后通过反射机制来调用这些方法。

 

   下面,通过一段代码,大家可以看看利用BeanInfo和Inspector如何实现内省:

 

   Person类:

public class Person { private String name; public int age; // public String xxx; // 定义set和get方法 public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { System.out.println("-----目标方法------"); return age; } public void setAge(int age) { this.age = age; } /* * public void setXxx(String xxx){ this.xxx=xxx; } */ //在这里,只要满足java定义的标准,都回算是一个对象,所以在测试类中,获取所有属性的PropertyDesciptor的数组长度为getClass()+所有满足java定义标准的get()方法的个数 public String getXxx() { return ""; } }

  测试类:

 

public class Demo { @Test public void test() throws Exception { // 1.获取beanInfo信息 BeanInfo beanInfo = Introspector.getBeanInfo(Person.class); // 返回一个BeanInfo信息() // 2.获取所有属性的PropertyDesciptor PropertyDescriptor pd[] = beanInfo.getPropertyDescriptors(); // getClass System.out.println(pd.length); // 遍历 for (PropertyDescriptor p : pd) { // System.out.println(p.toString()); Method m1 = p.getReadMethod();// 获得应该用于读取属性值的方法 System.out.println(m1.getName());// 获得应该用于写入属性值的方法 Method m2 = p.getWriteMethod(); if (m2 != null) { System.out.println(m2.getName()); } } } // 通过内省机制设置age字段的值 @Test public void test1() throws Exception { // 得到操作的class对象 Class c = Person.class; // 得到对象实例 Person p = (Person) c.newInstance(); // 得到class对象中的age字段的描述器对象 PropertyDescriptor pd = new PropertyDescriptor("age", c); // 获得此特性的本地化显示名称 // System.out.println(pd.getDisplayName()); // 得到age字段操作的写入方法对象 Method m = pd.getWriteMethod(); // 去执行目标p对象的目标方法(即pd.getWriteMethod()指向的方法),并为其age设置10的值 m.invoke(p, 10);// 设置值 // 查看是否成功 System.out.println(p.getAge()); } // 通过内省机制读取age字段的值 @Test public void test2() throws Exception { // 得到操作的class对象 Class c = Person.class; // 得到对象实例 Person p = (Person) c.newInstance(); p.setAge(100);// 设置值 // 得到class对象中的age字段的描述器对象 PropertyDescriptor pd = new PropertyDescriptor("age", c); // 获得此特性的本地化显示名称 // System.out.println(pd.getDisplayName()); // 得到age字段操作的读取方法对象 Method m = pd.getReadMethod(); // 去执行目标p对象的目标方法(即pd.getReadMethod()指向的方法),并为其age设置10的值 System.out.println("在执行目标方法之前所做的事情----"); Object value = m.invoke(p);// 设置值 // 查看是否成功 System.out.println(value); System.out.println("在执行目标方法之后所做的事情----"); } }

   在这里我同样用了JUnit测试内省的实现,大家可以自己测试一下,感受一下效果。

Sun 公司的内省 API 过于繁琐,所以 Apache 组织结合很多实际开发中的应用场景开发了一套简单、易用的 API 操作 Bean 的属性 —— BeanUtils。

 

   那么如何利用这个API来实现内省的实现呢?

 

   因为是人家公司封装的API,所以还是需要外界的jar包来实现此操作,这时我们就需要去相关网站去下载所需要的jar文件。下载下来后,解压找到下图所示的两个jar文件,添加到类库中。

  

java 解析省或直辖市 java内省的作用_apache

  细心的朋友也许会问到,我们需要的是BeanUtils这个Bean属性,那么下面的那个logging是干嘛的呢?

  先看一下的两段代码:

  Person类:

public class Person { private String name; public int age; 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; } }

   测试类:

public class Demo { @Test public void test() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException{ Person p=new Person();//实例化Bean对象 p.setName("Retror");//设置值 String value=BeanUtils.getProperty(p, "name");//获取指定Bean对象的制定属性值 System.out.println(value); } }

   如果我们没有配置下面的那个jar文件,那么在测试的时候就会出现如下异常错误:

 

/*java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory at org.apache.commons.beanutils.ConvertUtilsBean.(ConvertUtilsBean.java:157) at org.apache.commons.beanutils.BeanUtilsBean.(BeanUtilsBean.java:117) at org.apache.commons.beanutils.BeanUtilsBean$1.initialValue(BeanUtilsBean.java:68) at org.apache.commons.beanutils.ContextClassLoaderLocal.get(ContextClassLoaderLocal.java:153) at org.apache.commons.beanutils.BeanUtilsBean.getInstance(BeanUtilsBean.java:80) at org.apache.commons.beanutils.BeanUtils.getProperty(BeanUtils.java:382) at www.csdn.net.beanutils.Demo.test(Demo.java:15) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) at org.junit.runners.ParentRunner.run(ParentRunner.java:236) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory at java.net.URLClassLoader$1.run(URLClassLoader.java:366) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at java.lang.ClassLoader.loadClass(ClassLoader.java:423) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:356) ... 30 more*/这是因为,这个属性就是和logging这个日志记录一起的,如果没有这个记录就会出现错误。


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有