反射:反射机制

代码参考github上面

一、概念

Java Reflection      Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法

Java反射机制提供的功能 :

在运行时判断任意一个对象所属的类

在运行时构造任意一个类的对象

在运行时判断任意一个类所具有的成员变量和方法

在运行时调用任意一个对象的成员变量和方法

生成动态代理 

二、反射相关的主要API:

java.lang.Class:代表一个类

java.lang.reflect.Method:代表类的方法

java.lang.reflect.Field:代表类的成员变量

java.lang.reflect.Constructor:代表类的构造方法 。。。

三、Class 类

对照镜子后可以得到的信息:某个类的属性、方法和构造器、某个类到底实现了哪些接口。对于每个类而言,JRE 都为其保留一个不变的 Class 类型的对象。一个 Class 对象包含了特定某个类的有关信息。

Class本身也是一个类 Class 对象只能由系统建立对象 一个类在 JVM 中只会有一个Class实例 一个Class对象对应的是一个加载到JVM中的一个.class文件 每个类的实例都会记得自己是由哪个 Class 实例所生成 通过Class可以完整地得到一个类中的完整结构

方法名

功能说明

static Class  forName(String name) 

返回指定类名 name 的 Class 对象

Object newInstance() 

调用缺省构造函数,返回该Class对象的一个实例

getName() 

返回此Class对象所表示的实体(类、接口、数组类、基本类型或void)名称

Class getSuperClass()

返回当前Class对象的父类的Class对象

Class [] getInterfaces() 

获取当前Class对象的接口

ClassLoader getClassLoader() 

返回该类的类加载器

Class getSuperclass() 

返回表示此Class所表示的实体的超类的Class

Constructor[] getConstructors()

返回一个包含某些Constructor对象的数组

Field[] getDeclaredFields()

返回Field对象的一个数组

Method getMethod(String name,Class  …  paramTypes)

返回一个Method对象,此对象的形参类型为paramType

四、实例化Class类对象(四种方法)

)前提:若已知具体的类,通过类的class属性获取,该方法  最为安全可靠,程序性能最高        

实例:Class clazz = String.class;  Class cls = int.Type;

2)前提:已知某个类的实例,调用该实例的getClass()方法获 取Class对象        

实例:String s = "":      Class cls = s.getClass();

3)前提:已知一个类的全类名,且该类在类路径下,可通过 Class类的静态方法forName()获取,可能抛ClassNotFoundException        实例:Class clazz = Class.forName(“java.lang.String”);

4)其他方式(不做要求) ClassLoader cl = this.getClass().getClassLoader(); Class clazz4 = cl.loadClass(“类的全类名”); 


    @Test
    public void test3() throws ClassNotFoundException, IOException {

        ClassLoader load1 = ClassLoader.getSystemClassLoader();
        System.out.println(load1);//sun.misc.Launcher$AppClassLoader@18b4aac2


        ClassLoader load2 = load1.getParent();
        System.out.println(load2); //sun.misc.Launcher$ExtClassLoader@54bedef2


        ClassLoader load3 = load2.getParent();
        System.out.println(load3);//null

        String clasName  = "java.lang.String";
        Class<?> forName = Class.forName(clasName);
        ClassLoader load4 = forName.getClassLoader();
        System.out.println(load4);//sun.misc.Launcher$AppClassLoader@18b4aac2


        ClassLoader classLoader = this.getClass().getClassLoader();
        System.out.println(classLoader);
        Class<?> aClass = classLoader.loadClass("com.atguigu.reflect.Person");
        System.out.println(aClass);

        //掌握加载配文文件
        ClassLoader classLoader1 = this.getClass().getClassLoader();
        FileInputStream ins = new FileInputStream(new File("jdbc.peoperties"));
        InputStream in = classLoader1.getResourceAsStream("com\\atguigu\\reflect\\jdbc.properties");
        Properties p = new Properties();
        p.load(in);
        String user = p.getProperty("user");
        String pwd = p.getProperty("pwd");
        System.out.println(user);
        System.out.println(pwd);


    }

五、ClassLoader

类加载器是用来把类(class)装载进内存的。JVM 规范定义了两种类型的类加载器:启动类加载器(bootstrap)和用户自定义加载器(user-defined class loader)。 JVM在运行时会产生3个类加载器组成的初始化加载器层次结构 ,如下图所示:

引导类加载器:用C++编写的,是JVM自带的类加载器,负责Java平台核心库,用来加载核心类库。该加载器无法直接获取

扩展类加载器:负责jre/lib/ext目录下的jar包或 –D java.ext.dirs 指定目录下的jar包装入工作库

系统类加载器:负责java –classpath 或 –D java.class.path所指的目录下的类与jar包装入工作 ,是最常用的加载器 

//1.获取一个系统类加载器
ClassLoader classloader = ClassLoader.getSystemClassLoader();
System.out.println(classloader);
//2.获取系统类加载器的父类加载器,即扩展类加载器
classloader = classloader.getParent();
System.out.println(classloader);
//3.获取扩展类加载器的父类加载器,即引导类加载器
classloader = classloader.getParent();
System.out.println(classloader);
//4.测试当前类由哪个类加载器进行加载
classloader = 
Class.forName("exer2.ClassloaderDemo").getClassLoader();
System.out.println(classloader);

//5.测试JDK提供的Object类由哪个类加载器加载
classloader = 
Class.forName("java.lang.Object").getClassLoader();
System.out.println(classloader);
//*6.关于类加载器的一个主要方法:getResourceAsStream(String str):获取类路径下的指定文件的输入流
InputStream in = null;
in = this.getClass().getClassLoader().getResourceAsStream("exer2\\test.properties");
System.out.println(in);

六、创建类对象

创建类的对象,调用Class对象的newInstance()方法 要  求:    1)类必须有一个无参数的构造器。     2)类的构造器的访问权限需要足够。难道没有无参的构造器就不能创建对象了吗? 不是!只要在操作的时候明确的调用类中的构造方法,并将参数传递进去之后,才可以实例化操作。步骤如下: 1)通过Class类的getDeclaredConstructor(Class … parameterTypes)取得本类的指定形参类型的构造器 2)向构造器的形参中传递一个对象数组进去,里面包含了构造器中所需的各个参数。 3)通过Constructor实例化对象。

//1.根据全类名获取对应的Class对象
String name = “atguigu.java.Person";
Class clazz = null;
clazz = Class.forName(name);
//2.调用指定参数结构的构造器,生成Constructor的实例
Constructor con = clazz.getConstructor(String.class,Integer.class);
//3.通过Constructor的实例创建对应类的对象,并初始化类属性
Person p2 = (Person) 	con.newInstance("Peter",20);
System.out.println(p2);
public class CushContext {
	
	 private static final String[] CUSH_CLASS_NAME = {  
        "main.java.celue.celue5.CushNormal",  
        "main.java.celue.celue5.CushRebate",  
        "main.java.celue.celue5.CushReturn"
    }; 
	
	CushSuper cushSuper=null;
	public CushContext(String type,Class[] paramsType, Object[] parmas) {
		int type2=Integer.parseInt(type);
		try {
			Class<?> clazz=Class.forName(CUSH_CLASS_NAME[type2]);
			Constructor<?> constructor=clazz.getConstructor(paramsType);
			this.cushSuper=(CushSuper)constructor.newInstance(parmas);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
	}
	
	public double getResult(double money){
		return cushSuper.attachMoney(money);
	}
}

七、通过反射调用类的完整结构

Field、Method、Constructor、Superclass、Interface、Annotation

Field

package com.atguigu.testReflect;


import com.atguigu.reflect.Person;
import org.junit.Test;

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

/**
 *测试属性
 */

public class TestFileld {

    /**
     *  获取运行时类的属性
     */
    @Test
    public void test() {

        Class<Person> cla = Person.class;
        //只能获取(运行时类及父类到属性)修饰符为public的属性
        Field[] fields = cla.getFields();
        for(Field field:fields){
            System.out.println(field);
        }

        /**
         * getDeclaredFields  :只能获取运行时类本身定义的属性,包括私有属性
         */
        Field[] f2 = cla.getDeclaredFields();
        for(Field f : f2){
            System.out.println(f);
        }
    }

    /**
     * 属性的:权限修饰符,变量类型,变量名称,变量值
     * 获取属性的各个部分
     */
    @Test
    public void test2() {
        Class<Person> cla = Person.class;
        Field[] fields = cla.getDeclaredFields();
        for(Field f : fields){
            //权限修饰符
            int i = f.getModifiers();
            String s = Modifier.toString(i);
            System.out.print(s + " ");
            //变量类型
            Class<?> type = f.getType();
            System.out.print(type.getName()+" ");
            //变量名称
            String name = f.getName();
            System.out.println(name);
            System.out.println();
        }
    }


    /**
     * 获取指定类的属性
     */
    @Test
    public void test3() throws Exception {

        Class<Person> cls = Person.class;
        //获取指定的属性getField  只能获取运行时和父类中public的属性
        Field name = cls.getField("name");
        //创建运行时对象
        Person person = cls.newInstance();
        name.set(person,"王法");

        System.out.println(person);
        //获取属性的值
        Object o = name.get(person);
        System.out.println(o);

        //可以获取运行时类的声明的属性,包括私有的
        Field age = cls.getDeclaredField("age");
        //由于属性修饰符的限制,可以设置setAccessible为true,就可以操作私有属性
        age.setAccessible(true);
        age.set(person,10);
        System.out.println(person);

        Field id = cls.getDeclaredField("id");
        id.setAccessible(true);
        id.set(person,111);
        System.out.println(person);//Person{name='王法', age=10, id=111}


        //调用静态方法
、// 获取运行类中和父类中public的声明的方法
        Method info = cls.getMethod("info");
//        info.invoke(null);
        info.invoke(Person.class);


        //获取运行时中声明的方法
        Method method = cls.getDeclaredMethod("fly", String.class);
        method.setAccessible(true);
        Object china = method.invoke(person, "China");
        System.out.println(china);//1

    }

}

Method

package com.atguigu.testReflect;

import com.atguigu.reflect.Person;
import org.junit.Test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;
import java.lang.reflect.Type;
import java.sql.Types;

/**
 * Created by admin on 2019/5/10 17:26
 *
 * @Author: created by admin
 * @Date: created in 17:26 2019/5/10
 * @param: bindingResult
 * @param: result
 * @return:
 * @throws:
 * @Description:
 * @version:
 */

public class TestMethod {

    @Test
    public void test() {
        Class<Person> cla = Person.class;
        //获取运行时类中和父类中声明为public的方法
        Method[] methods = cla.getMethods();
        for(Method m:methods){
            System.out.println(m);
        }

        System.out.println();
        //获取运行时类本身声明的方法
        Method[] methods1 = cla.getDeclaredMethods();
        for(Method t : methods1){
            System.out.println(t);
        }
    }


    //注解,修饰符,返回值类型,方法名,形参列表,异常等
    @Test
    public void test2() {
        Class<Person> cla = Person.class;
        Method[] methods1 = cla.getDeclaredMethods();
        for(Method t : methods1){
            //注解
            Annotation[] as = t.getAnnotations();
            for(Annotation a :as){
                System.out.println(a);
            }

            //修饰符
            int modifiers = t.getModifiers();
            System.out.print(Modifier.toString(modifiers) +" ");

            //返回值类型
            Class<?> type = t.getReturnType();
            System.out.print(type+" ");
            //方法名
            System.out.print(t.getName()+" ");
            //形参列表
            System.out.print("(");
            Class<?>[] types = t.getParameterTypes();
            for(Class c : types){
                System.out.print(c.getName() +" ");
            }
            Parameter[] parameters = t.getParameters();
            for(Parameter p : parameters){
                System.out.print(p.getName()+" ");
            }
            System.out.print(")");

            //异常
            Class<?>[] types1 = t.getExceptionTypes();
            if(types1.length>0){
                System.out.print("throws  " );
            }
            for(Class c: types1){
                System.out.print(c.getName());
            }

            //
            Type[] types2 = t.getGenericExceptionTypes();

            for(Type c: types2){
                System.out.println(c.getTypeName());
            }
            System.out.println();
        }
    }


    /**
     * 获取运行时类的指定方法
     */
    @Test
    public void test3() throws Exception {

        Class<Person> cls = Person.class;
         //获取运行类中和父类中public的声明的方法
        Method show = cls.getMethod("show");
        System.out.println(show.getName());

        Person p = cls.newInstance();
        //调用方法
        Object invoke = show.invoke(p);
        System.out.println(invoke);

        Method toString = cls.getMethod("toString");
        Object invoke1 = toString.invoke(p);
        System.out.println(invoke1);

    }
}

Constructor

package com.atguigu.testReflect;


import com.atguigu.reflect.Person;
import org.junit.Test;

import java.lang.reflect.Constructor;

/**
 * Created by admin on 2019/5/13 21:25
 *
 * @Author: created by admin
 * @Date: created in 21:25 2019/5/13
 * @param: bindingResult
 * @param: result
 * @return:
 * @throws:
 * @Description:
 * @version:
 */

public class TestConstructor {
    @Test
    public void test() throws Exception {
        Class<?> cls = Class.forName("com.atguigu.reflect.Person");
        //创建对应的运行时对象,使用newInstance方法实际上调用的运行时类的空参构造器
        //要想能能创建成功,必须有空参构造器,并且权限要能足够
        Object o = cls.newInstance();
        Person p = (Person)o;
        System.out.println(p);
    }

    @Test
    public void  test1() throws Exception {
        //获取声明的所有的构造器
        Class<?> cls = Class.forName("com.atguigu.reflect.Person");
        Constructor<?>[] constructors = cls.getDeclaredConstructors();
        for(Constructor c:constructors){
            System.out.println(c);
        }
    }

    /**
     * 获取指定的构造器
     * @throws Exception
     */
    @Test
    public void test2() throws Exception {
        Class<?> cls = Class.forName("com.atguigu.reflect.Person");
        Constructor constructor = cls.getDeclaredConstructor(String.class, int.class);
        constructor.setAccessible(true);
        Person person = (Person) constructor.newInstance("王五", 23);
        System.out.println(person);
    }
}

 uperclass、Interface、Annotation其他等

package com.atguigu.testReflect;

import com.atguigu.reflect.Person;
import org.junit.Test;

import java.lang.annotation.Annotation;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * Created by admin on 2019/5/13 21:41
 *
 * @Author: created by admin
 * @Date: created in 21:41 2019/5/13
 * @param: bindingResult
 * @param: result
 * @return:
 * @throws:
 * @Description:
 * @version:
 */

public class TestOther  {

    //获取运行时的父类
    @Test
    public void test() {
        Class<Person> cls = Person.class;
        Class<? super Person> aClass = cls.getSuperclass();
        System.out.println(aClass);
    }

    //获取带泛型的父类getGenericSuperclass
    @Test
    public void test2() {
        Class<Person> cls = Person.class;
        Type type = cls.getGenericSuperclass();
        System.out.println(type);

    }

    //获取父类的泛型
    @Test
    public void test3() {
        Class<Person> cls = Person.class;
        Type type = cls.getGenericSuperclass();
        ParameterizedType t = (ParameterizedType)type;
        Type[] arguments = t.getActualTypeArguments();
        System.out.println(arguments.getClass());

        String typeName = arguments[0].getTypeName();
        //得到弗雷德泛型
        System.out.println(typeName);
        for(Type m:arguments) {
            System.out.println(m);
        }

    }

    /**
     * 获取实现的接口
     */
    @Test
    public void test4() {

        Class<Person> cls = Person.class;
        Class<?>[] interfaces = cls.getInterfaces();
        for(Class c: interfaces) {
            System.out.println(c);
        }
    }

    /**
     * 获取所在包
     */
    @Test
    public void test5() {

        Class<Person> cls = Person.class;
        Package aPackage = cls.getPackage();

        System.out.println(aPackage);
    }

    /**
     * 获取类注解
     */
    @Test
    public void test6() {

        Class<Person> cls = Person.class;
        Annotation[] annotations = cls.getAnnotations();
        for(Annotation a : annotations) {
            System.out.println(a );
        }
    }
}

八 、PropertyDescriptor类:(属性描述器)、Introspector类

内省(Introspector) 是Java 语言对JavaBean类属性、事件的一种缺省处理方法。
  JavaBean是一种特殊的类,主要用于传递数据信息,这种类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。如果在两个模块之间传递信息,可以将信息封装进JavaBean中,这种对象称为“值对象”(Value Object),或“VO”。方法比较少。这些信息储存在类的私有变量中,通过set()、get()获得。

@Data
public class UserInfo {

    private long userId;
    private String userName;
    private int age;
    private String emailAddress;
}

1、JDK内省类库:

PropertyDescriptor类:(属性描述器)
  PropertyDescriptor类表示JavaBean类通过存储器导出一个属性。主要方法:
  1. getPropertyType(),获得属性的Class对象;
  2. getReadMethod(),获得用于读取属性值的方法;
  3. getWriteMethod(),获得用于写入属性值的方法;
  4. hashCode(),获取对象的哈希值;
  5. setReadMethod(Method readMethod),设置用于读取属性值的方法;
  6. setWriteMethod(Method writeMethod),设置用于写入属性值的方法。

package com.peidasoft.instrospector;  

import java.beans.BeanInfo;  
import java.beans.Introspector;  
import java.beans.PropertyDescriptor;  
import java.lang.reflect.Method;  

public class BeanInfoUtil {  

    // 设置bean的某个属性值  
    public static void setProperty(UserInfo userInfo, String userName) throws Exception {  
        // 获取bean的某个属性的描述符  
        PropertyDescriptor propDesc = new PropertyDescriptor(userName, UserInfo.class);  
        // 获得用于写入属性值的方法  
        Method methodSetUserName = propDesc.getWriteMethod();  
        // 写入属性值  
        methodSetUserName.invoke(userInfo, "wong");  
        System.out.println("set userName:" + userInfo.getUserName());  
    }  

    // 获取bean的某个属性值  
    public static void getProperty(UserInfo userInfo, String userName) throws Exception {  
        // 获取Bean的某个属性的描述符  
        PropertyDescriptor proDescriptor = new PropertyDescriptor(userName, UserInfo.class);  
        // 获得用于读取属性值的方法  
        Method methodGetUserName = proDescriptor.getReadMethod();  
        // 读取属性值  
        Object objUserName = methodGetUserName.invoke(userInfo);  
        System.out.println("get userName:" + objUserName.toString());  
    }  
}

2、Introspector类:

将JavaBean中的属性封装起来进行操作。在程序把一个类当做JavaBean来看,就是调用Introspector.getBeanInfo()方法,得到的BeanInfo对象封装了把这个类当做JavaBean看的结果信息,即属性的信息。
  getPropertyDescriptors(),获得属性的描述,可以采用遍历BeanInfo的方法,来查找、设置类的属性。具体代码如下:

import java.beans.BeanInfo;  
import java.beans.Introspector;  
import java.beans.PropertyDescriptor;  
import java.lang.reflect.Method;  

public class BeanInfoUtil {  

    // 通过内省设置bean的某个属性值  
    public static void setPropertyByIntrospector(UserInfo userInfo, String userName) throws Exception {  
        // 获取bean信息  
        BeanInfo beanInfo = Introspector.getBeanInfo(UserInfo.class);  
        // 获取bean的所有属性列表  
        PropertyDescriptor[] proDescrtptors = beanInfo.getPropertyDescriptors();  
        // 遍历属性列表,查找指定的属性  
        if (proDescrtptors != null && proDescrtptors.length > 0) {  
            for (PropertyDescriptor propDesc : proDescrtptors) {  
                // 找到则写入属性值  
                if (propDesc.getName().equals(userName)) {  
                    Method methodSetUserName = propDesc.getWriteMethod();  
                    methodSetUserName.invoke(userInfo, "alan");  // 写入属性值  
                    System.out.println("set userName:" + userInfo.getUserName());  
                    break;  
                }  
            }  
        }  
    }  

    // 通过内省获取bean的某个属性值  
    public static void getPropertyByIntrospector(UserInfo userInfo, String userName) throws Exception {  
        BeanInfo beanInfo = Introspector.getBeanInfo(UserInfo.class);  
        PropertyDescriptor[] proDescrtptors = beanInfo.getPropertyDescriptors();  
        if (proDescrtptors != null && proDescrtptors.length > 0) {  
            for (PropertyDescriptor propDesc : proDescrtptors) {  
                if (propDesc.getName().equals(userName)) {  
                    Method methodGetUserName = propDesc.getReadMethod();  
                    Object objUserName = methodGetUserName.invoke(userInfo);  
                    System.out.println("get userName:" + objUserName.toString());  
                    break;  
                }  
            }  
        }  
    }  
}

3、BeanUtils工具包:

由上述可看出,内省操作非常的繁琐,所以所以Apache开发了一套简单、易用的API来操作Bean的属性——BeanUtils工具包。
  BeanUtils工具包:下载:BeanUtils – Commons,注意:应用的时候还需要一个logging包Apache Commons Logging - Overview
  使用BeanUtils工具包完成上面的测试代码:

package com.peidasoft.instrospector;  

import java.lang.reflect.InvocationTargetException;  
import org.apache.commons.beanutils.BeanUtils;  
import org.apache.commons.beanutils.PropertyUtils;  

public class BeanInfoTest {  

    /** 
     * @param args the command line arguments 
     */  
    public static void main(String[] args) {  
        UserInfo userInfo = new UserInfo();  
        userInfo.setUserName("peida");  
        try {  
            BeanUtils.setProperty(userInfo, "userName", "peida");  
            System.out.println("set userName:" + userInfo.getUserName());  
            System.out.println("get userName:" + BeanUtils.getProperty(userInfo, "userName"));  
            BeanUtils.setProperty(userInfo, "age", 18);  
            System.out.println("set age:" + userInfo.getAge());  
            System.out.println("get age:" + BeanUtils.getProperty(userInfo, "age"));  
            System.out.println("get userName type:" + BeanUtils.getProperty(userInfo, "userName").getClass().getName());  
            System.out.println("get age type:" + BeanUtils.getProperty(userInfo, "age").getClass().getName());  
            PropertyUtils.setProperty(userInfo, "age", 8);  
            System.out.println(PropertyUtils.getProperty(userInfo, "age"));  
            System.out.println(PropertyUtils.getProperty(userInfo, "age").getClass().getName());  
            PropertyUtils.setProperty(userInfo, "age", "8");  // IllegalArgumentException  
        } catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {  
            e.printStackTrace();  
        }  
    }  
}  

运行结果:
[java] view plain copy
set userName:peida  
get userName:peida  
set age:18  
get age:18  
get userName type:java.lang.String  
get age type:java.lang.String  

java.lang.Integer  
Exception in thread "main" java.lang.IllegalArgumentException: Cannot invoke com.peidasoft.instrospector.UserInfo.setAge on bean class   
    'class com.peidasoft.instrospector.UserInfo' - argument type mismatch - had objects of type "java.lang.String" but expected signature "int"  
    at org.apache.commons.beanutils.PropertyUtilsBean.invokeMethod(PropertyUtilsBean.java:2181)  
    at org.apache.commons.beanutils.PropertyUtilsBean.setSimpleProperty(PropertyUtilsBean.java:2097)  
    at org.apache.commons.beanutils.PropertyUtilsBean.setNestedProperty(PropertyUtilsBean.java:1903)  
    at org.apache.commons.beanutils.PropertyUtilsBean.setProperty(PropertyUtilsBean.java:2010)  
    at org.apache.commons.beanutils.PropertyUtils.setProperty(PropertyUtils.java:896)  
    at com.peidasoft.instrospector.BeanInfoTest.main(BeanInfoTest.java:32)  
Caused by: java.lang.IllegalArgumentException: argument type mismatch  
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)  
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)  
    at java.lang.reflect.Method.invoke(Method.java:483)  
    at org.apache.commons.beanutils.PropertyUtilsBean.invokeMethod(PropertyUtilsBean.java:2116)  
    ... 5 more
 

说明:
  1. 获得属性的值,例如,BeanUtils.getProperty(userInfo, “userName”),返回字符串。
  2. 设置属性的值,例如,BeanUtils.setProperty(userInfo, “age”, 8),参数是字符串或基本类型自动包装。设置属性的值是字符串,获得的值也是字符串,不是基本类型。

   
​​​​​​​        3. BeanUtils的特点:
  1). 对基本数据类型的属性的操作:在WEB开发、使用中,录入和显示时,值会被转换成字符串,但底层运算用的是基本类型,这些类型转到动作由BeanUtils自动完成。
  2). 对引用数据类型的属性的操作:首先在类中必须有对象,不能是null,例如,private Date birthday=new Date();。操作的是对象的属性而不是整个对象,例如,BeanUtils.setProperty(userInfo, “birthday.time”, 111111);

package com.peidasoft.Introspector;  
import java.util.Date;  

public class UserInfo {  

    private Date birthday = new Date(); // 引用类型的属性,不能为null  

    public void setBirthday(Date birthday) {  
        this.birthday = birthday;  
    }  
    public Date getBirthday() {  
        return birthday;  
    }        
}
package com.peidasoft.Beanutil;  

import java.lang.reflect.InvocationTargetException;  
import org.apache.commons.beanutils.BeanUtils;  
import com.peidasoft.Introspector.UserInfo;  

public class BeanUtilTest {  
    public static void main(String[] args) {  
        UserInfo userInfo=new UserInfo();  
         try {  
            BeanUtils.setProperty(userInfo, "birthday.time","111111");  // 操作对象的属性,而不是整个对象  
            Object obj = BeanUtils.getProperty(userInfo, "birthday.time");    
            System.out.println(obj);            
        }   
         catch (IllegalAccessException e) {  
            e.printStackTrace();  
        }   
         catch (InvocationTargetException e) {  
            e.printStackTrace();  
        }  
        catch (NoSuchMethodException e) {  
            e.printStackTrace();  
        }  
    }  
}

PropertyUtils类和BeanUtils不同在于,运行getProperty、setProperty操作时,没有类型转换,使用属性的原有类型或者包装类。由于age属性的数据类型是int,所以方法PropertyUtils.setProperty(userInfo,”age”, “8”)会爆出数据类型不匹配,无法将值赋给属性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 智慧社区背景与挑战 随着城市化的快速发展,社区面临健康、安全、邻里关系和服务质量等多方面的挑战。华为技术有限公司提出智慧社区解决方案,旨在通过先进的数字化技术应对这些问题,提升城市社区的生活质量。 2. 技术推动智慧社区发展 技术进步,特别是数字化、无线化、移动化和物联化,为城市社区的智慧化提供了可能。这些技术的应用不仅提高了社区的运行效率,也增强了居民的便利性和安全性。 3. 智慧社区的核心价值 智慧社区承载了智慧城市的核心价值,通过全面信息化处理,实现对城市各个方面的数字网络化管理、服务与决策功能,从而提升社会服务效率,整合社会服务资源。 4. 多层次、全方位的智慧社区服务 智慧社区通过构建和谐、温情、平安和健康四大社区模块,满足社区居民的多层次需求。这些服务模块包括社区医疗、安全监控、情感沟通和健康监测等。 5. 智慧社区技术框架 智慧社区技术框架强调统一平台的建设,设立数据中心,构建基础网络,并通过分层建设,实现平台能力及应用的可持续成长和扩展。 6. 感知统一平台与服务方案 感知统一平台是智慧社区的关键组成部分,通过统一的RFID身份识别和信息管理,实现社区服务的智能化和便捷化。同时,提供社区内外监控、紧急救助服务和便民服务等。 7. 健康社区的构建 健康社区模块专注于为居民提供健康管理服务,通过整合医疗资源和居民接入,实现远程医疗、慢性病管理和紧急救助等功能,推动医疗模式从治疗向预防转变。 8. 平安社区的安全保障 平安社区通过闭路电视监控、防盗报警和紧急求助等技术,保障社区居民的人身和财产安全,实现社区环境的实时监控和智能分析。 9. 温情社区的情感沟通 温情社区着重于建立社区居民间的情感联系,通过组织社区活动、一键呼叫服务和互帮互助平台,增强邻里间的交流和互助。 10. 和谐社区的资源整合 和谐社区作为社会资源的整合协调者,通过统一接入和身份识别,实现社区信息和服务的便捷获取,提升居民生活质量,促进社区和谐。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值