1 反射:
* 在运行时,我们可以获取任意一个类的所有方法和属性
* 在运行时,让我们调用任意一个对象的所有方法和属性
*
* 反射的前提:
* 要获取类的对象(Class对象)(字节码对象)
* 下面三种方式
*
*/public class A_ReflectDemo { public static void main(String[] args) throws ClassNotFoundException { // 第一种方式:通过Object的getClass()方法获取,必须要有对象 Student s = new Student(); Class clazz = s.getClass();//获取字节码对象 // 第二种方式:通过类名获取字节码对象 Class clazz2 = Student.class; //第三种:通过Class的forName方法, static Class> forName(String className) Class clazz3 = Class.forName("day18_20221115.Student"); System.out.println("判断:"+(clazz == clazz2)); System.out.println("判断:"+(clazz == clazz3)); System.out.println("clazz:"+clazz); } }
2 通过反射(字节码对象)获取构造方法并使用
* Constructor>[] getConstructors()
* Constructor>[] getConstructor()
*
* ConstructorgetConstructor(Class>... parameterTypes)
*
* T newInstance()
*
*Constructor:
* T newInstance(Object... initargs)
*/public class A_ReflectDemo2 { public static void main(String[] args) throws ReflectiveOperationException { Class clazz = Class.forName("day18_20221115.Student"); // method(clazz); // method2(clazz); // method3(clazz); //获取(无参构造)对象的另一种方法:字节码对象.newInstance!!! Object obj = clazz.newInstance(); System.out.println(obj); } private static void method3(Class clazz)throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { Constructor c = clazz.getConstructor(String.class,String.class,String.class,String.class);//获取有参构造,参数1类型为String,参数2类型为String... System.out.println(c); //获取对象的方法:将获取的构造方法.newInstance(参数1,2...) Object obj = c.newInstance("l001","xusp","18","广东上海"); System.out.println(obj); } private static void method2(Class clazz) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { Constructor c = clazz.getConstructor();//获取无参构造 System.out.println(c); //获取对象的方法:将获取的构造方法.newInstance() Object obj = c.newInstance();//创建学生对象了属于是!!(是相当于Student s = new Student();使用无参的) System.out.println(obj); } private static void method(Class clazz) { //Constructor>[] getConstructors() :获取所有public修饰的构造方法 Constructor[] cs = clazz.getConstructors(); for (int i = 0; i < cs.length; i++) { System.out.println(cs[i]); } } }
3 通过反射(字节码对象)获取成员变量并使用
* Field[] getFields()
* Field getField(String name)
*
* Field[] getDeclaredFields()
* Field getDeclaredField(String name)
*
* Field:
* Object get(Object obj)
* void set(Object obj, Object value)
*/public class A_ReflectDemo3 { public static void main(String[] args) throws ReflectiveOperationException { //获取学生类的字节码对象 Class clazz = Class.forName("day18_20221115.Student"); // method(clazz); System.out.println("------------------------------"); method2(clazz); } private static void method2(Class clazz) throws InstantiationException, IllegalAccessException, NoSuchFieldException { //获取学生类的对象(通过无参的方法) Object stu = clazz.newInstance(); //Field getField(String name) :根据字段名称获取公共的字段对象,public(若想获取别的修饰符,参考method) Field f = clazz.getField("age");//1.获取成员变量对象 System.out.println("age:"+f); //void set(Object obj, Object value) f.set(stu,"12");//2.通过成员变量对象,修改指定对为指定的值 //Object get(Object obj) Object age = f.get(stu);//3.通过对象获取成员变量的值 //注意:先获取成员变量f-->f.set(学生对象,"12")修改-->f.get(学生对象)获取,关键记住这两个get,set方法! System.out.println("age:"+age); System.out.println("stu:"+stu); } private static void method(Class clazz) { //Field[] getFields() :获取公共的成员变量,public Field[] fs = clazz.getFields(); for (int i = 0; i < fs.length; i++) { System.out.println(fs[i]); } System.out.println("----------"); //getDeclaredFields() :获取所有的成员变量,不管修饰符 Field[] fs2 = clazz.getDeclaredFields(); for (int i = 0; i < fs2.length; i++) { System.out.println(fs2[i]); } } }
4 通过反射(字节码对象)获取私有成员变量并使用
* Field[] getDeclaredFields()
* Field getDeclaredField(String name)
*/public class A_ReflectDemo4 { public static void main(String[] args) throws ReflectiveOperationException { //获取学生类的字节码对象 Class clazz = Class.forName("day18_20221115.Student"); //获取学生对象 Object stu = clazz.newInstance(); //获取私有的字段对象 Field f = clazz.getDeclaredField("sid"); f.setAccessible(true);//设置反射时取消Java的访问检查,暴力访问,就可以对私有变量进行操作了 System.out.println(f); f.set(stu, "l0086");//跟之前一样 Object sid = f.get(stu);//根之前一样 System.out.println(sid); } }
5 通过反射获取成员方法并使用
* Method getMethod(String name, Class>... parameterTypes)
* Method:
* Object invoke(Object obj, Object... args)
*
*/
public class B_ReflectDemo5 { public static void main(String[] args) throws ReflectiveOperationException { //获取学生类的字节码对象 Class clazz = Class.forName("day18_20221115.Student"); //获取学生类的对象 Object stu = clazz.newInstance(); method(clazz,stu); // method2(clazz,stu); // method3(clazz, stu); } private static void method3(Class clazz, Object stu) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { //获取无参有返回值的方法 Method m = clazz.getMethod("getSid"); Object obj = m.invoke(stu);//有返回值的方法调用要接收,不然就看不到,或者套在syso()内直接进行输出也可以看到! System.out.println(obj); } private static void method2(Class clazz, Object stu) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { //获取有参无返回值的方法,public类型 Method m = clazz.getMethod("setSid", String.class); m.invoke(stu, "10086");//对获取的方法进行参数传递 System.out.println(stu);//输出对象 } private static void method(Class clazz, Object stu) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { //获取无参无返回值的方法,要public类型的 Method m = clazz.getMethod("study");//public,获取成员方法 Method m1 = clazz.getDeclaredMethod("eat"); m1.setAccessible(true);//暴力执法 m.invoke(stu);//调用执行stu对象的m方法 m1.invoke(stu); } }
6 JavaBean的概述:
将需要操作的多个属性封装成JavaBean, 简单来说就是用于封装数据的规范:*
* JavaBean:用于封装数据
* 类使用公共进行修饰
* 提供私有修饰的成员变量
* 为成员变量提供公共getter和setter方法
* 提供公共无参的构造
* 实现序列号接口
*
*/public class C_Person implements Serializable { private static final long serialVersionUID = 1049712678750452511L;//身份证 private String name; private int age; private String gender; public C_Person() { super(); // TODO Auto-generated constructor stub } 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 String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", gender=" + gender + "]"; } }
BeanUtils:Apache commons提供的一个组件,主要功能就是为了简化JavaBean封装数据的操作
* 常见的成员方法:
* static void setProperty(Object bean, String name, Object value)
* static String getProperty(Object bean, String name)
* static void populate(Object bean, Map properties)
*
* 注意:BeanUtils的setProperty和getProperty方法底层并不是直接操作成员变量,而是操作和成员变量名有关的get和set方法(当person类的get,set方法注释掉就只有null咯)
*/public class C_BeanUtilsDemo { public static void main(String[] args) throws ReflectiveOperationException { // method(); method2(); } private static void method2() throws IllegalAccessException, InvocationTargetException { //static void populate(Object bean, Map properties) C_Person p = new C_Person(); Map
map = new HashMap (); //如果下面的key是错误的,那么实际对象并没有成功赋值,为null map.put("name", "lisi"); map.put("age", 18); map.put("gender", "male"); map.put("birthday", "2019-1");//如果给的映射关系不存在,不会报错,很灵活! BeanUtils.populate(p,map); System.out.println(p); } private static void method() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { C_Person p = new C_Person(); System.out.println(p); //static void setProperty(Object bean, String name, Object value) :给JavaBean对象的成员变量进行赋值 BeanUtils.setProperty(p, "name", "zhangsan"); BeanUtils.setProperty(p, "age", 18); System.out.println(p); //static String getProperty(Object bean, String name) String name = BeanUtils.getProperty(p, "name"); System.out.println(name); } }