北京市住房建设投资建设网站,重庆建筑人才网官网,福田做商城网站建设哪家技术好,做网站接私活流程目录 一.反射的简单解释与获取字节码文件对象
二.获取构造方法对象Constructor
三.反射获取字节码文件中的成员变量Field
四.反射获取字节码文件中的成员方法#xff1a;Method
五.反射练习#xff1a;保存信息
六.反射练习#xff1a;利用配置文件#xff08;存储类名…目录 一.反射的简单解释与获取字节码文件对象
二.获取构造方法对象Constructor
三.反射获取字节码文件中的成员变量Field
四.反射获取字节码文件中的成员方法Method
五.反射练习保存信息
六.反射练习利用配置文件存储类名和方法名)动态创建对象并调用方法
七.动态代理 一.反射的简单解释与获取字节码文件对象 反射允许对封装类的成员变量、构造方法、成员方法获取出来然后进行操作或者获取到如修饰符名字等更加详细的信息
没有反射怎么拿使用IO流但是比较麻烦这里就用反射咯 1.获取Class的有哪三种方式1.Class.forName(全类名)2.类名.class3.对象.getClass()
对应三个不同的阶段1.源代码编译时期2.加载阶段在内存当中的时候3.运行阶段已经有对象了
2.这三种方法获取的是什么对象 public class Demo351 {public static void main(String[] args) throws ClassNotFoundException {System.out.println(1获取Class的第一种方式需要传入全类名的字符串包含包名最为常用);System.out.println(IDEA中获取选择类名然后右键选择copy_Reference);Class? class1 Class.forName(Day35_Reflect_DynamicAgent.Demo351);System.out.println(class1);System.out.println(2获取Class的第二种方式通过类名调用);System.out.println(第二种则是多用于作为参数作为传递比如当作锁);Class? class2 Demo351.class;System.out.println(3获取Class的第三种方式通过对象调用也是获取的字节码文件);//已经有对象的时候才可以使用Class? class3 new Student().getClass();System.out.print(2.前两个类对象都是获取的字节码文件是同一个对象);System.out.println(class2class1);}
}
学生类JavaBean下面案例都是使用的此学生类
//四个构造方法两个是私有的
//有个成员方法抛出了异常
public class Student {private String name;private int age;public Student() {}private Student(String name) {this.name name;}private Student(int age) {this.age age;}public Student(String name, int age) {this.name name;this.age age;}public String getName() {return name;}public int getAge() {return age;}public void setName(String name) throws Exception{this.name name;}public void setAge(int age) {this.age age;}Overridepublic String toString() {return Student{ name name \ , age age };}
} 二.获取构造方法对象Constructor 从字节码文件里面获取数据对象的内容本类测试获取构造方法对象Constructor
1.使用什么方法获取所有公共构造方法呢
2.使用什么方法获取所有构造方法呢包括私有
3.获取单个构造方法时传入的参数应该是
4.如何获取构造方法内的权限修饰符
5.如何读取方法中的参数
6.如何使用私有构造方法创建变量 public class Demo352 {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {//获取字节码文件对象Class? studentClass Class.forName(Day35_Reflect_DynamicAgent.Student);System.out.println(1.使getConstructors获取构造方法获取所有公共构造方法);Constructor?[] constructors studentClass.getConstructors();for (Constructor? constructor : constructors) System.out.println(constructor);System.out.println(2.获取所有构造方法Declared:公开声明的);constructors studentClass.getDeclaredConstructors();for (Constructor? constructor : constructors) System.out.println(constructor);System.out.println(3.获取单个构造方法:指定构造方法可以传递参数:数据类型的字节码文件基本数据类型也要传.class字节码文件);Constructor? constructor studentClass.getConstructor();System.out.println(constructor);constructor studentClass.getConstructor(String.class,int.class);System.out.println(constructor);constructor studentClass.getDeclaredConstructor(int.class);System.out.println(constructor);//获取构造方法里面的内容System.out.println(4.使用getModifier方法读取权限修饰符内容是2的整数倍和底层运算效率有关左右移就能改变);//有什么用呢写IDEA源码有用,提示能够直接看到能传上面参数System.out.println(constructor.getModifiers());System.out.println(5.使用getParameters方法读取有哪些参数);Parameter[] parameters constructor.getParameters();for (Parameter parameter : parameters) System.out.println(parameter);System.out.println(6.使用构造方法创建对象私有方法不能够创建对象需要临时取消权限校验(暴力反射));System.out.println(首先把构造方法调用setAccessible方法传入true为参数);constructor.setAccessible(true);System.out.println(再使用构造方法的newInstance方法构造其对象);Student student (Student) constructor.newInstance(23);System.out.println(student);}
} 三.反射获取字节码文件中的成员变量Field 反射获取字节码文件中的成员变量Field
1.获取单个变量需要传入的参数
2.如何获取变量名
3.如何获取变量类型
4.如何获取对象中的变量的值
5.如何修改对象中变量的值 public class Demo353 {public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {//获取Field也是一样的方法Class? studentClass Class.forName(Day35_Reflect_DynamicAgent.Student);Field[] fields studentClass.getDeclaredFields();for (Field field : fields) System.out.println(field);System.out.println(1.获取单个成员变量传入变量名字符串);Field field studentClass.getDeclaredField(age);//获取成员变量信息System.out.println(field.getModifiers());System.out.println(2.使用getName方法获取变量名);System.out.println(field.getName());System.out.println(3.使用getType方法获取变量类型);Class? type field.getType();System.out.println(type);System.out.println(4.使用get方法传入某对象获取这个成员变量在该对象中的值同样也需要取消权限校验);field.setAccessible(true);Student student new Student(zhangsan, 123);Object age field.get(student);System.out.println(age);System.out.println(5.使用set方法传入某对象与修改的值对该对象中的成员变量修改);field.set(student,1234);System.out.println(student);}
}四.反射获取字节码文件中的成员方法Method 反射获取字节码文件中的成员方法Method
1.使用getMethods方法与getDeclaredMethods方法有什么区别
2.如何获取单个方法传入的参数是
3.如何返回方法抛出的异常
4.如何使用method对某对象调用方法传入的参数与返回的参数有什么特点 public class Demo354 {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {Class? studentClass Class.forName(Day35_Reflect_DynamicAgent.Student);Method[] methods studentClass.getMethods();System.out.println(1.使用getMethods方法同时也有继承与Object中的方法);for (Method method : methods)System.out.println(method);methods studentClass.getDeclaredMethods();System.out.println(获取所有方法的时候不会包含继承下来的方法);for (Method method : methods)System.out.println(method);System.out.println(2.通过名字和形参获取一个方法可以不加形参);Method method studentClass.getMethod(setName,String.class);System.out.println(method);//修饰符名字参数System.out.println(method.getModifiers());System.out.println(method.getName());for (Parameter parameter : method.getParameters())System.out.println(parameter);System.out.println(3.使用getExceptionTypes返回方法抛出的异常数组);System.out.println(Arrays.toString(method.getExceptionTypes()));System.out.println(4.调用invoke调用方法第一个参数传入对象第二个参数没有就不写方法没有返回也可以不写);Student student new Student();method.invoke(student,zhangsan);System.out.println(student);}
} 五.反射练习保存信息
对于任意一个对象把对象所有信息保存到文件当中对于不同的对象都可以如此操作
public class Demo355 {final static String FILE_STR D:\\IDEACode\\demo1\\JAVA基础\\src\\Day35_Reflect_DynamicAgent\\message.properties;public static void main(String[] args) throws IllegalAccessException, IOException {Student student new Student(zhansgan,123);Properties properties new Properties();Class? studentClass student.getClass();//获取字节码文件中的所有成员变量Field[] fields studentClass.getDeclaredFields();for (Field field : fields) {//设置取消检验field.setAccessible(true);//获取变量名String name field.getName();//获取对象中的该变量Object o field.get(student);properties.put(name,o.toString());}properties.store(new FileWriter(FILE_STR),addStudent);}
} 六.反射练习利用配置文件存储类名和方法名)动态创建对象并调用方法
public class Demo356 {final static String FILE_STR D:\\IDEACode\\demo1\\JAVA基础\\src\\Day35_Reflect_DynamicAgent\\prop.properties;public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {Properties properties new Properties();properties.load(new FileReader(FILE_STR));//获取字节码文件Class? aClass Class.forName((properties.get(classname).toString()));//获取构造方法创建对象Constructor? constructor aClass.getConstructor();Object o constructor.newInstance();//获取方法名并调用Method method aClass.getMethod(properties.get(method).toString());System.out.println(method.invoke(o));}
} 七.动态代理 动态代理不修改原有的代码又需要增加额外功能
为了程序的健壮性不改变原有代码的功能使用动态代理完成一些额外的事情
想要找某个核心人物做事情需要先找它的代理人去说要做的事情代理人里面也要有核心任务的方法 如何确定需要代理的方法呢
为了确定需要代理的方法需要让核心人物与代理人都实现某一个接口 需要代理的类
public class BigStar implements Star {private String name;public BigStar() {}public BigStar(String name) {this.name name;}Overridepublic String sing(String name){System.out.println(this.name正在唱:name);return 谢谢;}Overridepublic void dance(){System.out.println(跳舞);}public String getName() {return name;}public void setName(String name) {this.name name;}Overridepublic String toString() {return BigStar{ name name \ };}
}需要代理的方法的接口
public interface Star {String sing(String name);void dance();
}
代理工具类 用来创建代理对象
public class ProxyUtil {public static Star createProxy(BigStar bigStar) {System.out.println(1.创建静态方法返回一个代理人类型为BigStar实现的结构方法作用给明星对象创建一个代理形参被代理的明星对象返回一个接口也是返回代理对象);System.out.println(2.使用Proxy的newProxyInstance方法创建代理人对象传入三个参数);System.out.println(参数一指定类加载器加载生成的代理类找到谁加载了这个类参数二指定接口数组用于指定代理能代理哪些方法参数三指定代理要干什么事情在这个参数需要的对象需要实现的方法参数有三个参数一代理的对象,暂时用不到参数二要运行的方法参数三调用方法的时候需要传递的实参);Star star (Star) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(),new Class[]{Star.class},new InvocationHandler() {Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {/*参数一代理的对象,暂时用不到参数二要运行的方法参数三调用方法的时候需要传递的实参*/if (sing.equals(method.getName()))System.out.println(代理人准备话筒);else if (dance.equals(method.getName()))System.out.println(代理人准备场地);//返回运行结果return method.invoke(bigStar, args);}});return star;}
}
测试类
public class Demo361 {public static void main(String[] args) {//创建代理人Star proxy ProxyUtil.createProxy(new BigStar(mona));//使用代理人去调用方法System.out.println(proxy.sing(偶像宣言));proxy.dance();}
}