1, 类的编译和运行简易过程:
java 的源码文件 (也称为编译单元, 以. java 为后缀的文件)
文件内最多只能有一个 public 修饰的类, 否则编译器报错; 某个类被 public 修饰, 该类名必需与文件名称一致;
java 的字节码文件 (以. class 为后缀的文件)
源码文件经过编译器编译后产生的字节码文件, 源码文件中的每个类都会产生一个与类名相同的字节码文件
java 虚拟机解析字节码文件
加载. class 文件, 在内存里保持 Class 对象, 它被用来创建这个类的所有对象.
2, 获取 Class 对象的途径
Class.forName()
已知某个对象 w, 通过 w.getClass() 方法获取, 该方法在 Object 中
普通的类, 接口, 数组, 基本数据类型, 可以通过 .class 的形式获取, 如 char.class,Petty.class
3, 反射 -- 运行时的类型信息
什么是反射: 程序在运行时候, 可以通过类型信息获取类的域, 方法, 构造器等细节, 通过 java 的反射 API 可以调用这些域, 方法, 构造器等
反射的 API 在 java.lang.reflect 类库, Class 类的实例表示正在运行的 Java 应用程序中的类和接口, 因此可以获取 Field,Method,Constructor 类的对象等信息
4, 反射应用 -- 动态代理 (jdk 版)
- package com.leixingxinxi;
- public class Main {
- public static void main(String[] args) {
- TestFace testFace=new Person1();
- new Persion2(testFace).testDo();
- }
- }
- interface TestFace{
- void testDo();
- }
- class Person1 implements TestFace{
- public void testDo() {
- System.out.println("去买一杯咖啡...");
- }
- }
- class Persion2 implements TestFace{
- TestFace testFace;
- public Persion2(TestFace testFace){
- this.testFace=testFace;
- }
- public void testDo() {
- // 方法前的操作
- testFace.testDo();
- // 方法后的操作
- }
- }
- package com.leixingxinxi;
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Method;
- import java.lang.reflect.Proxy;
- public class Main {
- public static void main(String[] args) {
- TestFace proxy= (TestFace) Proxy.newProxyInstance(Persion1.class.getClassLoader(),Persion1.class.getInterfaces(),
- new MyInvocationHandler(new Persion1()));
- proxy.testDo();
- }
- }
- interface TestFace{
- void testDo();
- }
- class Persion1 implements TestFace{
- public void testDo() {
- System.out.println("去买一杯咖啡...");
- }
- }
- class MyInvocationHandler implements InvocationHandler{
- private TestFace testFace;
- public MyInvocationHandler(TestFace testFace){
- this.testFace=testFace;
- }
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- // 调用被代理对象的方法前的业务
- System.out.println("当前调用的方法为:"+method.getName());
- // 调用被代理对象方法
- method.invoke(testFace);
- // 调用被代理对象的方法后的业务
- System.out.println("被代理的方法调用结束");
- return null;
- }
- }
来源: https://www.cnblogs.com/shixiemayi/p/9398867.html