反射机制(五)

取得成员

        成员在类中也被称为属性,而在Class类里面针对于成员的取得也提供有如下的操作方法。

            取得全部成员:

                |-获得本类声明的成员:

 
public Field[] getDeclaredFields()
                          throws SecurityException

                 |-获得继承的声明成员:

public Field[] getFields()
                  throws SecurityException

            取得指定名称的成员:

                |-获得本类指定的成员:

public Field getDeclaredField(String name)
                       throws NoSuchFieldException,
                              SecurityException

                |-获得继承的声明成员:

                    在取得继承成员时,只能够取得所有的非私有化成员,

public Field getField(String name)
               throws NoSuchFieldException,
                      SecurityException

java.lang.reflect.Field是表示成员的类型,而在这个类里面定义有如下几个方法

            取得属性内容:

public Object get(Object obj)
           throws IllegalArgumentException,
                  IllegalAccessException

            取得属性类型:

   

public Class<?> getType()

            设置属性内容:

public void set(Object obj,
                Object value)
         throws IllegalArgumentException,
                IllegalAccessException

范例:取得全部的成员信息

import java.util.Date;
interface DD{
	public static final String aa="sssssssssss";
}
class Message{
	private String zhiye;
	private Date shijian;
}
public class Dome6_1 extends Message implements DD{
	private String name;
	private Integer age;
}

    此时的程序没有提供setter方法,只有封装属性.

import java.lang.reflect.Field;

public class Demo6 {
	public static void main(String[] args) throws ClassNotFoundException, IllegalArgumentException, IllegalAccessException {
		Class<?> cls=Class.forName("cn.zwb.dome1.Dome6_1");
		{		//取得全部成员
			Field fields[] =cls.getFields();
		for (int i = 0; i < fields.length; i++) {
				System.out.println(fields[i]);
		}
		}
		System.out.println("=========================");
		{		//取得本类成员
			Field fields[] =cls.getDeclaredFields();
			for (int i = 0; i < fields.length; i++) {
					System.out.println(fields[i]);
			
		}
		}
	}
}

    在实际开发之中,以上的操作时没有任何意义的,只有在IDE工具上会使用,但是Field类可以做

以下两件事情:

       可以取得指定成员的类型

       可以直接操作属性,可以完全避免掉Method操作;

    但是需要注意的是,这种直接操作属性的情况是不允许出出现的,而且所有的属性时使用了private封装的,但是这种封装是可以解除的(Field,Method.Constructor的父类):

public void setAccessible(boolean flag)
                   throws SecurityException

设置为true表示取消封装,默认为false.

范例:设置和取得属性

import java.lang.reflect.Field;

public class Demo6 {
	public static void main(String[] args) throws ClassNotFoundException, IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException, InstantiationException {
		Class<?> cls=Class.forName("cn.zwb.dome1.Dome6_1");
		Object obj=cls.newInstance();//属性必须有对象产生才可以操作。
		Field nameField=cls.getDeclaredField("name");
		nameField.setAccessible(true);//取消封装
		System.out.println("类型:"+nameField.getType().getSimpleName());
		nameField.set(obj,"詹闻博");
		System.out.println(nameField.get(obj));
}
}

    但是这样的做法是不标准的,因为所有设置属性和取得属性还是应该编写setter和getter方法,也就是所在整个开发过程之中,Field类给予我们最大支持是取得属性类型.

范例:解决属性设置问题

import java.util.Date;
public class Dome6_1{
	private String name;
	private Integer age;
	private Date credate;
	private Double costs;
}//生成setter个getter方法

现在还是给出你字符串.

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.text.SimpleDateFormat;

import cn.zwb.util.StringUtils;

public class Demo6 {
	public static void main(String[] args) throws ClassNotFoundException, IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException, InstantiationException, NoSuchMethodException, InvocationTargetException, ParseException {
		String str="name:詹闻博|age:21|credate:1997-06-06|costs:80000.0";
		Class<?> cls=Class.forName("cn.zwb.dome1.Dome6_1");
		Object obj=cls.newInstance();
		String[] re=str.split("\\|");
		for (int i = 0; i < re.length; i++) {
			String temp[] =re[i].split(":");
			Field field=cls.getDeclaredField(temp[0]);
			Method setMet=cls.getDeclaredMethod("set"+StringUtils.initcap(temp[0]),field.getType());
			if("string".equalsIgnoreCase(field.getType().getSimpleName())){
				setMet.invoke(obj, temp[1]);
			}else if("int".equalsIgnoreCase(field.getType().getSimpleName())||"integer".equalsIgnoreCase(field.getType().getSimpleName())){
				if(temp[1].matches("\\d+")){
					setMet.invoke(obj, Integer.parseInt(temp[1]));
				}
			}else if("double".equalsIgnoreCase(field.getType().getSimpleName())){
				if(temp[1].matches("\\d+(\\.\\d{1,2})?")){
					setMet.invoke(obj, Double.parseDouble(temp[1]));
				}
			}else if("date".equalsIgnoreCase(field.getType().getSimpleName())){
				if(temp[1].matches("\\d{4}-\\d{2}-\\d{2}")){
					setMet.invoke(obj, new SimpleDateFormat("yyyy-MM-dd").parse(temp[1]));
				}
			}
		}
		System.out.println(obj);
}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值