在Java反射中Field用于获取某个类的属性或该属性的属性值
一:如何通过Field反射获取类的属性
Field提供如下几种方法:
1:Class.getDeclaredField(String name); 返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段(包括私有成员)。 2:Class.getDeclaredFields(); 返回 Field 对象的一个数组,该数组包含此 Class 对象所表示的类或接口所声明的所有字段(包括私有成员)。 3:Class.getField(String name); 返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。 4:Class.getFields(); 返回一个包含某些 Field 对象的数组,该数组包含此 Class 对象所表示的类或接口的所有可访问公共字段。
|
下面一个例子说明如何通过Field反射获取类中的属性
我们先定义一个普通类Person
包含三个属性 公有name 私有age、sex
package testReflect;
public class Person {
public String name;
private Integer age;
private String sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", sex=" + sex
+ "]";
}
}
Test类 测试
package testReflect;
import java.lang.reflect.Field;
/**
* 通过Field反射的各方法访问属性
* @author 5_6-TANGZHANBO
*
*/
public class Test
{
public static void main(String[]args) throws NoSuchFieldException, SecurityException
{
Person p = new Person();
p.setAge(30);
//通过Class.getDeclaredField(String name)获取类或接口的指定的已声明字段。
Field f1 = p.getClass().getDeclaredField("name");
System.out.println("f1==="+f1);
//通过Class.getDeclaredFields()获取类或接口的指定已声明字段。
Field[] f2 = p.getClass().getDeclaredFields();
for (Field field : f2) {
System.out.println("f2--field "+field);
}
//Class.getField(String name)用法
//通过Class.getField(String name)返回一个类或接口的指定的公共成员字段,私有成员报错。
Field f3_0 = p.getClass().getField("name");
System.out.println("f3_0==="+f3_0);
//如果获取age属性(私有成员) 则会报错 ,age是private
//Field f3_1 = p.getClass().getField("age");//Exception in thread "main" java.lang.NoSuchFieldException: age
//System.out.println("f3_1==="+f3_1);
//Class.getFields()用法
//通过Class.getFields(),返回 Class 对象所表示的类或接口的所有可访问公共字段。
Field f4 [] = p.getClass().getFields();
for (Field field : f4) {
//因为只有name属性为共有,因此只能遍历出name属性
System.out.println("f4--field "+field);
}
}
}
测试结果:
===========================================================================================
User:
package entity;
public class User {
private int id;
private int age;
private String name;
//javabean 必须要有无参构造方法
public User() {
super();
}
public User(int id, int age, String name) {
super();
this.id = id;
this.age = age;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User [id=" + id + ", age=" + age + ", name=" + name + "]";
}
}
TestReflect:
package testReflect;
@SuppressWarnings("all")
public class TestReflect {
public static void main(String[] args) {
String path = "entity.User";
try {
Class<?> clazz = Class.forName(path);
System.out.println(clazz);
System.out.println(clazz.hashCode());
Class<?> clazz2 = Class.forName(path);
System.out.println(clazz2==clazz);//反射只创建一个对象
Class<String> strClazz=String.class;
Class<? extends String> strClazz2 = path.getClass();
System.out.println(strClazz==strClazz2);
Class<Integer> intClazz = int.class;
int[] arr01= new int[10];
int[] arr02 =new int[30];//反射创建对象 与数组长度没关系 ,与数组的类型有关系
int [][] arr03 =new int [30][3];
double [] arr04 = new double[10];
System.out.println(arr01.getClass().hashCode());
System.out.println(arr02.getClass().hashCode());
System.out.println(arr03.getClass().hashCode());
System.out.println(arr04.getClass().hashCode());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
TestReflect2:
package testReflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
@SuppressWarnings("all")
public class TestReflect2 {
public static void main(String[] args) {
String path = "entity.User";
try {
Class clazz = Class.forName(path);
//获取类的名字
System.out.println(clazz.getName());
System.out.println(clazz.getSimpleName());
//获取属性信息
Field [] fields = clazz.getFields();//只能获得public的field
Field [] fields2 = clazz.getDeclaredFields();//可以获取所有field
System.out.println(fields.length);
Field f = clazz.getDeclaredField("name");
System.out.println(fields2.length);
for (Field field : fields2) {
System.out.println("属性 :"+field);
}
//获取方法信息
Method [] methods = clazz.getDeclaredMethods();
Method m01 = clazz.getDeclaredMethod("getName", null);
Method m02 = clazz.getDeclaredMethod("setName", String.class);//有参数的情况下,这里要写参数类型 重载
for (Method method : methods) {
System.out.println("method :"+method);
}
//获得构造器信息
Constructor [] constructors = clazz.getDeclaredConstructors();
Constructor c = clazz.getDeclaredConstructor(null);
System.out.println("获得构造器: "+c);
for (Constructor constructor : constructors) {
System.out.println("constructor : "+constructor);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
TestReflect3:
package testReflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import entity.User;
/**
* 通过反射可以动态的操作构造器,方法和属性
* @author Administrator
*
*/
@SuppressWarnings("all")
public class TestReflect3 {
public static void main(String[] args) {
String path = "entity.User";
try {
Class<User> clazz = (Class<User>)Class.forName(path);
User u = clazz.newInstance();//javabean 必须要有无参构造方法 没有的话 报错:java.lang.InstantiationException: entity.User
System.out.println(u);
Constructor<User> c = clazz.getDeclaredConstructor(int.class,int.class,String.class);//通过参数类型,获取对应的构造方法
User u2 = c.newInstance(1,26,"花");
System.out.println(u2.getName());
//通过反射api 调用普通方法
User u3 = clazz.newInstance();
//调方法1 直接调用
// u3.setName("花和尚");
//调方法2 反射的方式:通过反射获取这个方法再调用
Method method = clazz.getDeclaredMethod("setName", String.class);//反射的好处:方法名可以做参数,比如方法名可以从浏览器过来也可以从数据库或文件里读,传来什么参数就调用什么方法,这就是反射的好处。实现动态的调用。
method.invoke(u3, "花和尚");//调用
System.err.println(u3.getName());
//通过反射api操作属性
User u4 = clazz.newInstance();
Field f = clazz.getDeclaredField("name");
f.setAccessible(true);//表示不用不需要做安全检查了,可以直接访问。
f.set(u4, "花和尚波");//给哪个对象设置属性,通过反射直接写属性,这里 不能访问私有属性报错:java.lang.IllegalAccessException: Class testPro.test.TestReflect3 can not access a member of class entity.User with modifiers "private"
System.out.println(u4.getName());//通过反射直接读属性
System.out.println(f.get(u4));//把f的值 获取到
} catch (Exception e) {
e.printStackTrace();
}
}
}