`
luoxiaohui_java
  • 浏览: 12879 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Java反射机制学习(二)

阅读更多

先来看一个通过反射来动态给变量赋值的:

package com.reflect.demo;

public class Student {

	public String name;

	public  Integer age;

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Student(String name, Integer age) {
		super();
		this.name = name;
		this.age = age;
	}

	public Student() {
		super();
	}

}
package com.reflect.demo;

import java.lang.reflect.Field;

public class BaseTest {

	public static void main(String[] args) throws SecurityException,
			NoSuchFieldException, IllegalArgumentException,
			IllegalAccessException {
		Student stu1 = new Student();
		Field nameField1 = Student.class.getField("name");
		nameField1.set(stu1, "张三");
		System.out.println("学生1的姓名为:" + stu1.getName() + " \t 年龄为:"
				+ stu1.getAge());

	}

}

 

通过反射机制来实现在程序运行中动态给变量赋值,需要考虑以下几点:

 

1)如何获取相应的Filed,Method对象?

2)怎样将动态的值设置到目标对象?

3)碰到私有域变量Field和方法Method如何处理?

 

 

对于第一点,主要是获取Class对象。有三种方法获取Class对象

a.   类名.class   b. 对象名.getClass()  例如用stu1.getClass()代替 Student.class结果完全一样

c.   Class.forName("类名");

 

对于第二点,代码nameField1.set(stu1, "张三");是关键,第一个参数即为目标对象。亦即通过Field对象的

set方法给对象stu1的name属性赋值。

 

对于第三点,若要给age赋值,但age在Student类中是私有变量,是不容许外部类访问的。这时候想起上一章节中

提到的抽象类AccessibleObject提供了setAccessible方法,该方法可以跳过Java 语言访问控制检查。

 

 

代码如下:

Student stu1 = new Student();
       Student stu2 = new Student();
       Field  nameField1 = stu1.getClass().getField("name");
       nameField1.set(stu1, "张三");
       System.out.println("学生1的姓名为:"+stu1.getName()+" \t 年龄为:"+stu1.getAge());
       
       
         Field  ageField2 = stu2.getClass().getDeclaredField("age");
       ageField2.setAccessible(true);
       ageField2.set(stu2, 18);       
       System.out.println("学生2的姓名为:"+stu2.getName()+" \t 年龄为:"+stu2.getAge());
  

 

 

还有得注意的是:

 1)、注意getField与getDeclaredField的区别:两者都是java.lang.Class类提供的方法,前者用于取指定类或接口的公有属性,而age是私有属性必须用后者来获取。

 

2)、在此不能用ageField2.setInt(stu2,18)代替ageField2.set(stu2, 18),这里做了严格的校验,Student中age属性采用了Integer类型。

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics