概述
反射:框架设计的灵魂
框架:半成品软件。可以在框架的基础上进行软件开发,简化编码
反射:将类的各个组成部分封装为其他对象,反射机制
好处:
1.可以在程序运行过程中,操作这些对象
2.可以解耦,提高程序的可扩展性
获取class对象的方式:
1、Class.forName(“全类名”):将字节码文件加载进内存,返回class对象
多用于配置文件,将类名定义在配置文件中,读取文件,加载类
2、类名.class:通过类名的属性class获取
多用于参数的传递
3、对象.getClass(): getClass()方法在Object类中定义
多用于对象的获取字节码的方式
同一个字节码文件(.class)在一次程序运行过程中,只会被加载一次,不论通过哪种方式获取的class对象*
//第一种方式
Class cls1 = Class.forName("domain.Person");
System.out.println(cls1);
//第二种方式
Class cls2 = Person.class;
System.out.println(cls2);
//第三种方式
Person p =new Person();
Class cls3= p.getClass();
System.out.println(cls3);
//比较这三个对象
System.out.println(cls1==cls2);
System.out.println(cls1==cls3);
System.out.println(cls2==cls3);
Class对象功能
获取:
1、获取成员变量
Field[] getFields()
Field getField(String name)
Field[] getDeclaredFields()
Field getDeclaredField(String name)
public class Reflectdemo02 {
public static void main(String[] args) throws Exception {
//1
Class perclass = Person.class;
Field[] fields = perclass.getFields(); //获取所有public修饰的成员变量
for (Field field : fields) {
System.out.println(field);
}
System.out.println("----------");
//Field getField(String name)
Field a =perclass.getField("a");
//获取成员变量a的值
Person p =new Person();
Object value =a.get(p);
System.out.println(value);
//设置a的值
a.set(p,"jackboy");
System.out.println(p);
System.out.println("---------");
//Field[] getDeclaredFields()获取所有的成员变量 不考虑修饰符
Field[] declaredFields = perclass.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
//Field getDeclaredField(String name)
Field d = perclass.getDeclaredField("age");
//需要忽略访问修饰符的安全检查
d.setAccessible(true);//暴力反射
Object value2 = d.get(p);
System.out.println(value2);
}
}
2、获取构造方法
Constructor<?> getConstructors()
Constructor getConstructor(Class<?>… parameterTypes)
Constructor<?>[] getDeclaredConstructors()
Constructor getDeclaredConstructor(Class<?>… parameterTypes)
public class Reflectdemo03 {
public static void main(String[] args) throws Exception{
Class pers = Person.class;
//Constructor<?> getConstructors()
Constructor constructors = pers.getConstructor(String.class, int.class);
System.out.println(constructors);
//Constructor:构造方法 用来创建对象
Object person = constructors.newInstance("jackboy", 23);
System.out.println(person);
System.out.println("-----------");
Constructor constructors1 = pers.getConstructor();
System.out.println(constructors1);
//Constructor:构造方法 用来创建对象
Object person1 = constructors.newInstance("jackboy", 23);
System.out.println(person);
pers.newInstance();
}
}
3、获取成员方法
Method[] getMethods()
Method getMethod(String name, Class<?>… parameterTypes)
(加上Declared)
public class Reflectdemo04 {
public static void main(String[] args) throws Exception{
Class pers = Person.class;
/**
* Method[] getMethods()
* Method getMethod(String name, Class<?>… parameterTypes)
* 获取指定名称的方法
*/
Method eat = pers.getMethod("eat");
Person p = new Person();
//执行方法
eat.invoke(p);
Method eat1 = pers.getMethod("eat", String.class);
eat1.invoke(p,"吃饭");
System.out.println("--------");
//获取所有public修饰的方法 包括隐藏的方法
Method[] methods = pers.getMethods();
for (Method method : methods) {
System.out.println(method);
//获取方法名
String name = method.getName();
System.out.println(name);
//method.setAccessible(true);
}
//获取类名
String name = pers.getName();
System.out.println(name);
}
}
4、获取类名
String getName()
String name = pers.getName();
System.out.println(name);
暴力反射
忽略访问修饰符的安全检查
setAccessible(true)