反射(三)之通过反射获取构造方法, 成员变量, 成员方法
一.通过反射获取构造方法并使用
获取构造方法
getConstructors
getDeclaredConstructors
创建对象
newInstance()
con.newInstance(“zhangsan", 20);
二.通过反射获取成员变量并使用
获取所有成员
getFields,getDeclaredFields
获取单个成员
getField,getDeclaredField
修改成员的值
set(Object obj,Object value)
将指定对象变量上此 Field 对象表示的字段设置为指定的新值。
三.通过反射获取成员方法并使用
获取所有方法
getMethods
getDeclaredMethods
获取单个方法
getMethod
getDeclaredMethod
暴力访问(否则会报Illegalxxx...Exception...)
method.setAccessible(true);
注意:
getDeclaredConstructors, getDeclaredFields, getDeclaredMethods, 这里加Declared是可以获取非public声明的构造方法, 成员变量, 成员方法.(否则会报NoSuch.....Exception...)
四.示例
4.1 首先自定义Person类
1 package cn.itcast_01; 2 3 public class Person { 4 private String name; 5 int age; 6 public String address; 7 8 public Person() { 9 } 10 11 private Person(String name) { 12 this.name = name; 13 } 14 15 Person(String name, int age) { 16 this.name = name; 17 this.age = age; 18 } 19 20 public Person(String name, int age, String address) { 21 this.name = name; 22 this.age = age; 23 this.address = address; 24 } 25 26 public void show() { 27 System.out.println("show"); 28 } 29 30 public void method(String s) { 31 System.out.println("method " + s); 32 } 33 34 public String getString(String s, int i) { 35 return s + "---" + i; 36 } 37 38 private void function() { 39 System.out.println("function"); 40 } 41 42 @Override 43 public String toString() { 44 return "Person [name=" + name + ", age=" + age + ", address=" + address 45 + "]"; 46 } 47 48 }
4.2 通过反射获取构造方法并使用
4.2.1 通过反射获取构造方法并使用
1 package cn.itcast_02; 2 3 import java.lang.reflect.Constructor; 4 5 import cn.itcast_01.Person; 6 7 /* 8 * 通过反射获取构造方法并使用。 9 */ 10 public class ReflectDemo { 11 public static void main(String[] args) throws Exception { 12 // 获取字节码文件对象 13 Class c = Class.forName("cn.itcast_01.Person"); 14 15 // 获取构造方法 16 // public Constructor[] getConstructors():所有公共构造方法 17 // public Constructor[] getDeclaredConstructors():所有构造方法 18 // Constructor[] cons = c.getDeclaredConstructors(); 19 // for (Constructor con : cons) { 20 // System.out.println(con); 21 // } 22 23 // 获取单个构造方法 24 // public Constructor<T> getConstructor(Class<?>... parameterTypes) 25 // 参数表示的是:你要获取的构造方法的构造参数个数及数据类型的class字节码文件对象 26 Constructor con = c.getConstructor();// 返回的是构造方法对象 27 28 // Person p = new Person(); 29 // System.out.println(p); 30 // public T newInstance(Object... initargs) 31 // 使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。 32 Object obj = con.newInstance(); 33 System.out.println(obj); 34 35 // Person p = (Person)obj; 36 // p.show(); 37 } 38 }
4.2.2 通过反射去获取该构造方法并使用
1 package cn.itcast_02; 2 3 import java.lang.reflect.Constructor; 4 5 /* 6 * 需求:通过反射去获取该构造方法并使用: 7 * public Person(String name, int age, String address) 8 * 9 * Person p = new Person("林青霞",27,"北京"); 10 * System.out.println(p); 11 */ 12 public class ReflectDemo2 { 13 public static void main(String[] args) throws Exception { 14 // 获取字节码文件对象 15 Class c = Class.forName("cn.itcast_01.Person"); 16 17 // 获取带参构造方法对象 18 // public Constructor<T> getConstructor(Class<?>... parameterTypes) 19 Constructor con = c.getConstructor(String.class, int.class, 20 String.class); 21 22 // 通过带参构造方法对象创建对象 23 // public T newInstance(Object... initargs) 24 Object obj = con.newInstance("林青霞", 27, "北京"); 25 26 System.out.println(obj); 27 } 28 }
4.2.3 通过反射获取私有构造方法并使用
1 package cn.itcast_02; 2 3 import java.lang.reflect.Constructor; 4 5 /* 6 * 需求:通过反射获取私有构造方法并使用 7 * private Person(String name){} 8 * 9 * Person p = new Person("风清扬"); 10 * System.out.println(p); 11 */ 12 public class ReflectDemo3 { 13 public static void main(String[] args) throws Exception { 14 // 获取字节码文件对象 15 Class c = Class.forName("cn.itcast_01.Person"); 16 17 // 获取私有构造方法对象 18 // NoSuchMethodException:每个这个方法异常 19 // 原因是一开始我们使用的方法只能获取公共的,下面这种方式就可以了。 20 Constructor con = c.getDeclaredConstructor(String.class); 21 22 // 用该私有构造方法创建对象 23 // IllegalAccessException:非法的访问异常。 24 // 暴力访问 25 con.setAccessible(true);// 值为true则指示反射的对象在使用时应该取消Java语言访问检查。 26 Object obj = con.newInstance("风清扬"); 27 28 System.out.println(obj); 29 } 30 }
4.3 通过反射获取成员变量并使用
1 package cn.itcast_03; 2 3 import java.lang.reflect.Constructor; 4 import java.lang.reflect.Field; 5 6 /* 7 * 通过发生获取成员变量并使用 8 */ 9 public class ReflectDemo { 10 public static void main(String[] args) throws Exception { 11 // 获取字节码文件对象 12 Class c = Class.forName("cn.itcast_01.Person"); 13 14 // 获取所有的成员变量 15 // Field[] fields = c.getFields(); 16 // Field[] fields = c.getDeclaredFields(); 17 // for (Field field : fields) { 18 // System.out.println(field); 19 // } 20 21 /* 22 * Person p = new Person(); p.address = "北京"; System.out.println(p); 23 */ 24 25 // 通过无参构造方法创建对象 26 Constructor con = c.getConstructor(); 27 Object obj = con.newInstance(); 28 System.out.println(obj); 29 30 // 获取单个的成员变量 31 // 获取address并对其赋值 32 Field addressField = c.getField("address"); 33 // public void set(Object obj,Object value) 34 // 将指定对象变量上此 Field 对象表示的字段设置为指定的新值。 35 addressField.set(obj, "北京"); // 给obj对象的addressField字段设置值为"北京" 36 System.out.println(obj); 37 38 // 获取name并对其赋值 39 // NoSuchFieldException 40 Field nameField = c.getDeclaredField("name"); 41 // IllegalAccessException 42 nameField.setAccessible(true); 43 nameField.set(obj, "林青霞"); 44 System.out.println(obj); 45 46 // 获取age并对其赋值 47 Field ageField = c.getDeclaredField("age"); 48 ageField.setAccessible(true); 49 ageField.set(obj, 27); 50 System.out.println(obj); 51 } 52 }
4.4 通过反射获取成员方法并使用
1 package cn.itcast_04; 2 3 import java.lang.reflect.Constructor; 4 import java.lang.reflect.Method; 5 6 public class ReflectDemo { 7 public static void main(String[] args) throws Exception { 8 // 获取字节码文件对象 9 Class c = Class.forName("cn.itcast_01.Person"); 10 11 // 获取所有的方法 12 // Method[] methods = c.getMethods(); // 获取自己的包括父亲的公共方法 13 // Method[] methods = c.getDeclaredMethods(); // 获取自己的所有的方法 14 // for (Method method : methods) { 15 // System.out.println(method); 16 // } 17 18 Constructor con = c.getConstructor(); 19 Object obj = con.newInstance(); 20 21 /* 22 * Person p = new Person(); p.show(); 23 */ 24 25 // 获取单个方法并使用 26 // public void show() 27 // public Method getMethod(String name,Class<?>... parameterTypes) 28 // 第一个参数表示的方法名,第二个参数表示的是方法的参数的class类型 29 Method m1 = c.getMethod("show"); 30 // obj.m1(); // 错误 31 // public Object invoke(Object obj,Object... args) 32 // 返回值是Object接收,第一个参数表示对象是谁,第二参数表示调用该方法的实际参数 33 m1.invoke(obj); // 调用obj对象的m1方法 34 35 System.out.println("----------"); 36 // public void method(String s) 37 Method m2 = c.getMethod("method", String.class); 38 m2.invoke(obj, "hello"); 39 System.out.println("----------"); 40 41 // public String getString(String s, int i) 42 Method m3 = c.getMethod("getString", String.class, int.class); 43 Object objString = m3.invoke(obj, "hello", 100); 44 System.out.println(objString); 45 // String s = (String)m3.invoke(obj, "hello",100); 46 // System.out.println(s); 47 System.out.println("----------"); 48 49 // private void function() 50 Method m4 = c.getDeclaredMethod("function"); 51 m4.setAccessible(true); 52 m4.invoke(obj); 53 } 54 }
作者:习惯沉淀
如果文中有误或对本文有不同的见解,欢迎在评论区留言。
如果觉得文章对你有帮助,请点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
扫码关注一线码农的学习见闻与思考。
回复"大数据","微服务","架构师","面试总结",获取更多学习资源!