天天看点

java反射详解,原理分析

反射原理分析

1、反射

1.1、反射原理

1、类的加载
当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化。
□   加载 
就是指将class文件读入内存,并为之创建一个Class对象。
任何类被使用时系统都会建立一个Class对象
□   连接
验证 是否有正确的内部结构,并和其他类协调一致
准备 负责为类的静态成员分配内存,并设置默认初始化值
解析 将类的二进制数据中的符号引用替换为直接引用
□   初始化 
类的加载

2、  类加载器
□   负责将.class文件加载到内在中,并为之生成对应的Class对象。
□   虽然我们不需要关心类加载机制,但是了解这个机制我们就能更好的理解程序的运行

3、类加载器的组成
□   Bootstrap ClassLoader 根类加载器
也被称为引导类加载器,负责Java核心类的加载
比如System,String等。在JDK中JRE的lib目录下rt.jar文件中
□   Extension ClassLoader 扩展类加载器
负责JRE的扩展目录中jar包的加载。
在JDK中JRE的lib目录下ext目录
□   System ClassLoader 系统类加载器
负责在JVM启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和类路径。
           

2.1、公共类

A接口

public interface A {

    }
           

B接口

public interface B {

    }
           

User类

public class User implements A,B{

        private String username;    

        private String password;


        public User() {

        }

        public User(String username, String password) {
            this.username = username;
            this.password = password;
        }

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }

        @Override
        public String toString() {
            return "User [username=" + username + ", password=" + password + "]";
        }

    }
           

2.1、三种方式获取类的字节码文件的对象

//三种方式获得 类的字节码文件 的对象
 //1、方式 通过类.class来获取  类的字节码文件 的对象
 Class clazz = User.class;
 System.out.println(clazz);

 //2、方式 通过对象.getClass()来获取  类的字节码文件 的对象
 User user = new User();
 Class class1 = user.getClass();
 System.out.println(class1);

 //3、通过Class.froName()来获取  类的字节码文件 的对象
 Class class2 = Class.forName("com.itheima.reflect.User");
 System.out.println(class2);

 System.out.println(class1==class2);//true
 System.out.println(clazz==class2);//true
           

2.2、获取构造器并创建对象。

//通过Class.froName()来获取  类的字节码文件 的对象
Class clazz = Class.forName("com.itheima.reflect.User");


//无参数的
//通过class对象获取类的构造器。
Constructor constructor = clazz.getConstructor();
//通过构造器创建对象
User user = (User)constructor.newInstance();
System.out.println(user);

//有参数的

//通过class对象获取类的构造器。
Constructor c2 = clazz.getConstructor(String.class,String.class);
//通过构造器创建对象
User user2 = (User)c2.newInstance("zhangsan","123");
System.out.println(user2);
           

2.3、获取方法并执行

//通过Class.froName()来获取  类的字节码文件 的对象
Class clazz = Class.forName("com.itheima.reflect.User");
//通过clazz对象创建一个User的对象
User user = (User)clazz.newInstance();


//获取有参数的方法并执行
//通过getMethod获取clazz对象里面的方法
Method method = clazz.getMethod("setUsername", String.class);
method.invoke(user, "lisi");

//获取无参数的方法并执行
Method method1 = clazz.getMethod("getUsername");
String name = (String)method1.invoke(user);

System.out.println(user);
System.out.println(name);
           

2.4、获得类的所有的接口

//三种方式获得 类的字节码文件 的对象
//1、方式 通过类.class来获取  类的字节码文件 的对象
Class clazz = User.class;
Class[] interfaces = clazz.getInterfaces();

for (Class class1 : interfaces) {
  System.out.println(class1);
}