java反射

来源:互联网 发布:md5算法是不是对称加密 编辑:程序博客网 时间:2024/06/17 00:38

反射就是把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);//trueSystem.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();}@Overridepublic 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;}@Overridepublic 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.namefield = 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.sexfield = clz.getDeclaredField("name");//java.lang.NoSuchFieldExceptionSystem.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
原创粉丝点击