java反射

反射就是把Java类中的各种成分映射成相应的java类。例如,一个Java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的Java类来表示,就像汽车是一个类,汽车中的发动机,变速箱等等也是一个个的类。表示java类的Class类显然要提供一系列的方法,来获得其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应类的实例对象来表示,它们是Field、Method、Contructor、Package等等.......

首先要用反射必须要获得某个java类的Class类的对象,有三种方式:

Class<?> clz1 = String.class;
Class<?> clz2 = new String().getClass();
Class<?> clz3 = Class.forName("java.lang.String");
System.out.println(clz1==clz2);//true
System.out.println(clz2==clz3);//true
以上三种方式获得的运行时类的 Class 对象在内存中只有一个,因此直接比较地址是相同的..........

接下来将简单介绍一下Class类中的方法:

一.定义两个个测试类,里面包含一些成员变量,构造器,方法等

1>Person类,包含名字(name)和年龄(age)两个属性

public class Person {
	public String name;
	private int age;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public Person(String name) {
		super();
		this.name = name;
	}
	public Person() {
		super();
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
}


2>Man类,继承自Person类,添加了性别(sex)属性

public class Man extends Person {
	private char sex;
	public char getSex() {
		return sex;
	}
	public void setSex(char sex) {
		this.sex = sex;
	}
	public Man(String name, int age, char sex) {
		super(name, age);
		this.sex = sex;
	}
	@Override
	public String toString() {
		return "Man [sex=" + sex + ", toString()=" + super.toString() + "]";
	}
}
二.Class类提供了四种方法获取成员变量,分别是getField,getFileds,getDeclaredField,getDeclaredFields

1>getField(String name):返回此 Class 对象所表示的类或接口的指定公共成员字段(从父类继承的也算),如果没有这个字段或者不是public修饰的,则抛出java.lang.NoSuchFieldException

Man user = new Man("张三",20,'男');
Class<?> clz = user.getClass();
Field field = clz.getField("name");
System.out.println(field);//public java.lang.String com.java5.reflect.test.Person.name
field = clz.getField("sex");//java.lang.NoSuchFieldException
2>getFields(): 返回此  Class 对象所表示的类或接口的 所有 公共成员字段( 从父类继承的也算

3>getDeclaredField(String name):返回此 Class 对象指定已声明字段(当前Class对象对应的类中声明的,继承实现的不算

Man user = new Man("张三",20,'男');
Class<?> clz = user.getClass();
Field field = clz.getDeclaredField("sex");
System.out.println(field);//private char com.java5.reflect.test.Man.sex
field = clz.getDeclaredField("name");//java.lang.NoSuchFieldException
System.out.println(field);
4>getDeclaredFields():返回此  Class 对象所有已声明字段( 当前Class对象对应的类中声明的,继承实现的不算

获得了Field之后,我们就可以调用各种方法获取相应的信息(注释后面为打印到控制台的值)

Man user = new Man("张三",20,'男');
Class<?> clz = user.getClass();
Field field = clz.getDeclaredField("sex");
System.out.println(user);//Man [sex=男, toString()=Person [name=张三, age=20]]
//sex成员变量是private修饰的,要设置值其accessible为true,否者抛出java.lang.IllegalAccessException异常
field.setAccessible(true);
//设置user对象sex的值
field.set(user, '女');
System.out.println(user);//Man [sex=女, toString()=Person [name=张三, age=20]]
//获取user对象sex的值
System.out.println(field.get(user));//女
//获取属性名
System.out.println(field.getName());//sex
//获取这个属性的访问修饰符,返回值是整形数值,在Modifier有详细的定义
System.out.println(field.getModifiers());//打印2,private在Modifier类中有十六进制表示为0x00000002
//判断这个属性是不是private修饰的,
System.out.println(Modifier.isPrivate(field.getModifiers()));//true
//获得这个属性的类型
System.out.println(field.getType());//char

三.类似的,Class类也提供了四种方法获取类中的方法:getMethod,getMethods,getDeclaredMethod,getDeclaredMethods,这四种方法跟Field里面的类似,只不过把属性换成了方法,因此对这四种方法不再做详细介绍,下面直接介绍Method类里面一些方法的用法..

Man user = new Man("张三",20,'男');
Class<?> clz = user.getClass();
Method method = clz.getDeclaredMethod("setSex", char.class);
System.out.println(user);//Man [sex=男, toString()=Person [name=张三, age=20]]
//判断该方法是不是private修饰的
System.out.println(Modifier.isPrivate(method.getModifiers()));//false
//如果是private修改的,则需要修改accessible为true,否者执行invoke方法报java.lang.IllegalAccessException
//method.setAccessible(true);
//相当于执行user.setSex('女')方法
method.invoke(user, '女');
System.out.println(user);//Man [sex=女, toString()=Person [name=张三, age=20]]
//获取方法名
System.out.println(method.getName());//setSex
//获取声明次method对象的类名
System.out.println(method.getDeclaringClass());//class com.java5.reflect.test.Man
//获取返回值类型
System.out.println(method.getReturnType());//void
//获取参数的类型
Class<?>[] clzs = method.getParameterTypes();
System.out.println(clzs[0].getName());//char
//判断是否带有可变参数
System.out.println(method.isVarArgs());//false
//获取方法上声明的注解
Annotation[] annotations = method.getDeclaredAnnotations();
System.out.println(annotations.length);//0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值