Java:反射:Field用法

在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();
		}
	}

}

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值