1.2 常用方法Class.forName(“类的全路径”); 注意:传入的是类的全路径名,包含包名.类名,而且会抛出异常
类名.class 注意:这个写法需要自己手动接一下获取到的字节码对象,不能用快捷方式的
对象.getClass(); 注意:经常与匿名对象一起使用
获取包名 类名
clazz.getPackage().getName()//包名 clazz.getSimpleName()//类名 clazz.getName()//完整类名
获取成员变量定义信息
getFields()//获取所有公开的成员变量,包括继承变量 getDeclaredFields()//获取本类定义的成员变量,包括私有,但不包括继承的变量 getField(变量名) getDeclaredField(变量名)
获取构造方法定义信息
getConstructor(参数类型列表)//获取公开的构造方法 getConstructors()//获取所有的公开的构造方法 getDeclaredConstructors()//获取所有的构造方法,包括私有 getDeclaredConstructor(int.class,String.class)
获取方法定义信息
getMethods()//获取所有可见的方法,包括继承的方法 getMethod(方法名,参数类型列表) getDeclaredMethods()//获取本类定义的的方法,包括私有,不包括继承的方法 getDeclaredMethod(方法名,int.class,String.class)
反射新建实例
clazz.newInstance();//执行无参构造创建对象 clazz.getConstructor(int.class,String.class)//要先获取构造方法 clazz.newInstance(666,”海绵宝宝”);//再执行含参构造创建对象
反射调用成员变量
clazz.getDeclaredField(变量名);//获取变量 field.setAccessible(true);//使私有成员允许访问 field.set(实例,值);//为指定实例的变量赋值,静态变量,第一参数给null field.get(实例);//访问指定实例变量的值,静态变量,第一参数给null
反射调用成员方法
Method m = Clazz.getDeclaredMethod(方法名,参数类型列表); m.setAccessible(true);//使私有方法允许被调用 m.invoke(实例,参数数据);//让指定实例来执行该方法
package cn.tedu.reflection; public class Student{ //1.定义成员变量 public String name; public int age; //2.提供本类的无参与全参构造 public Student(String name, int age) { this.name = name; this.age = age; } public Student() { } public void play(){ System.out.println("今天大结局,放学后写10000行代码"); } public void eat(int n){ System.out.println("在忙我也要吃"+n+"碗大米饭"); } //4.重写toString(),为了查看对象的类型 属性 属性值 @Override public String toString() { return "Student{" + "name='" + name + ''' + ", age=" + age + '}'; } }
package cn.tedu.reflection; import org.junit.Test; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Arrays; public class TestReflect { @Test public void getClazz() throws ClassNotFoundException { //练习获取字节码对象的3种方式 Class> Clazz1 = Class.forName("cn.tedu.reflection.Student"); Class> Clazz2 = Student.class; Class extends Student> Clazz3 = new Student().getClass(); System.out.println(Clazz1.getClass().getName());//java.lang.Class System.out.println(Clazz1);//class cn.tedu.reflection.Student System.out.println(Clazz1.getName());//cn.tedu.reflection.Student System.out.println(Clazz1.getSimpleName());//Student System.out.println(Clazz1.getPackage());//package cn.tedu.reflection System.out.println(Clazz1.getPackage().getName());//cn.tedu.reflection } @Test public void getFie() throws ClassNotFoundException { //1.获取字节码对象 Class> clazz = Class.forName("cn.tedu.reflection.Student"); //2.通过字节码对象,获取目标类中所有的成员变量 Field[] fs = clazz.getFields(); //3.遍历数组,获取每个成员变量的具体信息 for (Field f : fs) { System.out.println(f.getName());//name age System.out.println(f.getType());//class java.lang.String int // name // class java.lang.String // age // int } } @Test public void getSu() { //1.创建Student类的3个对象 Student s1 = new Student("张三", 3); Student s2 = new Student("李四", 4); Student s3 = new Student("王五", 5); //2.将创建好的3个对象放入Student类型的数组中 Student[] s = {s1, s2, s3}; //3.通过遍历,在每轮循环获取每一个学生对象 for (Student hh : s) { System.out.println(hh.name); hh.eat(8); hh.play(); } } @Test public void getFunction() { //1.获取字节码对象 Class> clazz = Student.class; //通过字节码对象获取目标类对应的所有成员方法们 Method[] ms = clazz.getMethods(); //3.通过高效for循环遍历数组,每轮循环拿到一个方法对象 for (Method s : ms) { // System.out.println(s+" "); // public java.lang.String cn.tedu.reflection.Student.toString() // public void cn.tedu.reflection.Student.play() // public void cn.tedu.reflection.Student.eat(int) // public final void java.lang.Object.wait() throws java.lang.InterruptedException // public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException // public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException // public boolean java.lang.Object.equals(java.lang.Object) // public native int java.lang.Object.hashCode() // public final native java.lang.Class java.lang.Object.getClass() // public final native void java.lang.Object.notify() // public final native void java.lang.Object.notifyAll() // System.out.println("方法名字"+s.getName()); // 方法名字toString // 方法名字play // 方法名字eat // 方法名字wait // 方法名字wait // 方法名字wait // 方法名字equals // 方法名字hashCode // 方法名字getClass // 方法名字notify // 方法名字notifyAll //通过本轮循环获取到方法对象,进一步获取这个方法的参数类型 Class>[] pt = s.getParameterTypes(); // System.out.println(pt); // [Ljava.lang.Class;@5e8c92f4 // [Ljava.lang.Class;@61e4705b // [Ljava.lang.Class;@50134894 // [Ljava.lang.Class;@2957fcb0 // [Ljava.lang.Class;@1376c05c // [Ljava.lang.Class;@51521cc1 // [Ljava.lang.Class;@1b4fb997 // [Ljava.lang.Class;@deb6432 //[Ljava.lang.Class;@28ba21f3 // [Ljava.lang.Class;@694f9431 // [Ljava.lang.Class;@f2a0b8e System.out.println(Arrays.toString(pt)); // [] //[] //[int] //[] //[long, int] //[long] //[class java.lang.Object] //[] //[] //[] //[] } } @Test public void getCons(){ //1.获取字节码对象 Class extends Student> clazz= new Student().getClass(); //2.通过字节码对象 获取目标类中的构造方法们 Constructor>[] cs = clazz.getConstructors(); //3.通过高效for循环遍历,拿到每一个构造函数对象 for (Constructor c: cs) { System.out.println(c.getName());//cn.tedu.reflection.Student cn.tedu.reflection.Student Class[] pt = c.getParameterTypes(); for (Class p: pt ) { System.out.println(Arrays.toString(pt));//[class java.lang.String, int] [class java.lang.String, int] } } } @Test public void getObject() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { //1.获取字节码对象 Class> clazz = Student.class; //2.利用反射创建目标业务类对象 Object o = clazz.newInstance(); System.out.println(o);//Student{name='null', age=0} //3.获取指定的构造函数对象,注意要获取构造方法,需要指定参数类型,而且是字节码对象 Constructor> c = clazz.getConstructor(String.class ,int.class); //4.利用获取到的全参构造对象,创建目标类Student的对象 //构造方法 传参数 Object o2 = c.newInstance("赵六", 18); //5.打印创建好的学生类对象,可以看到属性也被赋值了 System.out.println(o2); } }练习2
package cn.tedu.reflection; public class Person { //1.提供私有属性 private String name; private int age; private String addr; //2.提供私有方法 private void save(int n,String s){ System.out.println("save方法"+n+s); } private void update(){ System.out.println("update方法"); } }
package cn.tedu.reflection; import org.junit.Test; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Testreflect2 { @Test public void getFile2() throws Exception { //1.获取字节码对象 Class> clazz = Person.class; //2.获取指定它的私有属性,注意需要传入属性名,确认要获取哪个私有属性 Field field = clazz.getDeclaredField("name"); //3.根据获取到的属性值,查看属性的类型 System.out.println(field);//private java.lang.String cn.tedu.reflection.Person.name System.out.println(field.getType().getName());//java.lang.String System.out.println(field.getType());//class java.lang.String //4.设置属性的值 //4.1需要指定到底给哪个对象的name属性设置一个什么值 Object obj = clazz.newInstance();//触发无参构造创建对象 //4.2暴力反射,需要设置私有资源可见权限 field.setAccessible(true); //fileld就是我们刚刚获取的name值 //set(m,n)---m是给哪个对象的name属性设置值,n是设置的具体值 field.set(obj, "赵六"); //4.4打印查看刚刚的属性值是否设置成功 //filed.get(m),m代表的就是给哪个对象的这个name属性的值 System.out.println(field.get(obj));//赵六 } @Test public void getFile3() throws NoSuchFieldException, IllegalAccessException, InstantiationException { Class> clazz = Person.class;//获取字节码对象 Field addr = clazz.getDeclaredField("addr");//获取addr属性对象 addr.setAccessible(true);//设置属性私有可见的权限 Object o = clazz.newInstance();//准备好要给哪个对象设置属性值 addr.set(o, "北京");//给p3对象的field(addr属性)设置值为“北京” System.out.println(addr.get(o));//北京,查看属性值是否设置成功 } @Test public void getFunction2() throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException { //1.获取字节码对象 Class extends Person> clazz = new Person().getClass(); //2.通过字节码对象获取私有方法 Method save = clazz.getDeclaredMethod("save", int.class, String.class); //通过反射创建目标类Person对应的对象 Person p1 = clazz.newInstance(); save.setAccessible(true); save.invoke(p1, 18, "秦仙女");//save方法18秦仙女 } @Test public void getFunction3() throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException { Class> clazz = Person.class; Method update = clazz.getDeclaredMethod("update"); update.setAccessible(true); Object o = clazz.newInstance(); update.invoke(o);//update方法 } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)