反射
反射:加载类,并允许以编程的方式解剖类中的各种成分,成员变量,方法,构造器等等;
反射的作用,反射主要还是用来做框架
反射学什么?学习获取类的信息并操作他们
1,反射第一步,加载类,获取类的字节码,class对象
2,获取类的构造器,construceor对象
3,获取类的成员变量,field对象
4,获取对象的成员方法, method对象
获取类的Class对象的三种方式
1,Class c1 = 类名.class
2,调用Class提供的方法: public static Class forName(String package); 获取class对象
3,Object提供的方法: public Class getClass(); Class c3 = 对象.getClass();
获取类中的构造器
例如我们想要获取上述中Student的类构造器
package org.example; import java.lang.reflect.Constructor; public class TestClass2 { public static void main(String[] args) { Class c1 = Student.class; for (Constructor constructor : c1.getConstructors()) { System.out.println(constructor); //constructor构造器 System.out.println(constructor.getName()+"构造器参数数量: "+constructor.getParameterCount()); //getParameterCount获取构造器参数数量 } } }
打印之后则会输出
public org.example.Student(java.lang.String,int)
org.example.Student构造器参数数量: 2
public org.example.Student()
org.example.Student构造器参数数量: 0
其他的方法(代码实例):
package org.example; import java.lang.reflect.Constructor; public class TestClass2 { public static void main(String[] args) throws NoSuchMethodException { Class c1 = Student.class; for (Constructor constructor : c1.getConstructors()) { System.out.println(constructor); //constructor构造器 System.out.println(constructor.getName()+"构造器参数数量: "+constructor.getParameterCount()); //getParameterCount获取构造器参数数量 } for (Constructor declaredConstructor : c1.getDeclaredConstructors()) { System.out.println(declaredConstructor.getName()); /** * getDeclaredConstructors获取全部构造器包括私有成员 * 可以无视修饰符修饰后的构造器 */ } //getConstructor获取单个构造器,只能拿public修饰的构造器 Constructor constructor = c1.getConstructor(); //无参构造器 Constructor constructor2 = c1.getConstructor(String.class,int.class); //有参构造器 //getDeclaredConstructor可以获取任何类型的构造器 Constructor dconstructor = c1.getDeclaredConstructor(); //无参构造器 Constructor dconstructor2 = c1.getDeclaredConstructor(String.class,int.class); //有参构造器 } }
通过反射获取类的构造器的作用: 依旧是初始化类的对象并且返回
Construcror提供的方法
//getConstructor获取单个构造器,只能拿public修饰的构造器 Constructor<Student> constructor = c1.getConstructor(); //无参构造器 Constructor constructor2 = c1.getConstructor(String.class,int.class); //有参构造器 //getDeclaredConstructor可以获取任何类型的构造器 Constructor<Student> dconstructor = c1.getDeclaredConstructor(); //无参构造器 Constructor dconstructor2 = c1.getDeclaredConstructor(String.class,int.class); //有参构造器 dconstructor.setAccessible(true); //设置true可以暴力反射对象,无视私有属性 Student s = dconstructor.newInstance(); //newInstance初始化对象并且返回 System.out.println(s);
通过反射获取类的成员变量,并且对成员变量进行操作
@Test public void testOprFieldClass() throws NoSuchMethodException, NoSuchFieldException, IllegalAccessException { //第一步, 获取类的Class对象 Class c1 = Student.class; /** * 第二步,获取类全部的成员变量 * getFields 只获取public修饰的成员变量 * getDeclaredFields获取所有成员变量 * getField 获取单个成员变量 只获取public修饰的成员变量 * getDeclaredField 获取单个成员变量,不过可以获取任意成员变量 */ Field[] fields = c1.getDeclaredFields(); for (Field field : fields) { System.out.println("成员变量: "+field.getName()+"---->"+field.getType()); //getName获取成员变量名字,getType获取成员变量类型 } Field field = c1.getDeclaredField("name"); field.setAccessible(true); //暴力反射 Student s = new Student(); //实例化Student对象 field.set(s,"小明"); //set给成员变量进行赋值 System.out.println(s.toString()); System.out.println(field.get(s)); //get取值 }
通过反射获取类的成员方法,并且对成员方法进行操作
@Test public void testOprMethodClass() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { //第一步,获取反射Class对象 Class c1 = Student.class; /** * 2,获取类的全部成员方法 */ Method[] methods = c1.getDeclaredMethods(); for (Method method : methods) { System.out.println(method.getName()); //getname获取成员方法名称 System.out.println(method.getParameterCount()); //getParameterCount获取方法参数数量 System.out.println(method.getReturnType()); //获取成员方法返回类型 } Student student = new Student("小明",12); Method run = c1.getMethod("getName"); run.setAccessible(true); Object rs = run.invoke(student); System.out.println(rs); }
反射的作用
基本作用:
1,获取一个类的全部成分然后进行操作
2,并且可以破坏封装性
3,适合做JAVA的框架,主流的框架都会基于反射设计出来一些通用的功能