Java学习笔记--反射

来源:互联网 发布:linux sed命令 编辑:程序博客网 时间:2024/05/24 04:16

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

<2>类的加载时机
2.1 创建类的实例
2.2 访问类的静态变量,或者为静态变量赋值
2.3 调用类的静态方法
2.4 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
2.5 初始化某个类的子类
2.6 直接使用java.exe命令来运行某个主类
<3>加载器分类
a.根类加载器:也成为引导类加载器,负责加载Java的核心类,有Bootstrap,ClassLoader,在JDK中JRE的lib目录下rt.jar文件中
b.扩展类加载器:负责JRE的扩展目录中jar包的加载,在JDK中JRE的lib目录下的ext目录
c.系统类加载器:负责在JVM启动时加载来自java命令的class文件
二,反射
1.反射定义
通过已知字节码文件对象,使用该类中的成员,每个class字节码文件会对应的生成一个该字节码文件对应的字节码文件对象。
2.获取字节码文件方法
A.Object类的getClass()方法
B.数据类型的静态Class属性
C.Class类的静态方法forName(“所需类的完全限定名”)
代码实现:`

    import java.lang.reflect.Constructor;    public class ConstructorDemo {public static void main(String[] args) throws Exception {    Class<?> c = Class.forName("com.yang_o1.Person");    Constructor<?>[] cons = c.getConstructors();    for (Constructor<?> con : cons) {        System.out.println(con);//public com.yang_o1.Person()    }    System.out.println("---");    Constructor<?>[] cons2 = c.getDeclaredConstructors();    for (Constructor<?> con : cons2) {        System.out.println(con);//所有声明的构造方法    }    System.out.println("---");    Constructor<?> con = c.getConstructor();    System.out.println(con);//public com.yang_o1.Person()    Object obj = con.newInstance();    System.out.println(obj);    System.out.println("---");    Constructor<?> con2 = c.getDeclaredConstructor(String.class,int.class,String.class);    con2.setAccessible(true);    Object obj2 = con2.newInstance("陈奕迅", 45, "香港");    System.out.println(obj2);//Person [name=陈奕迅, age=45, address=香港]    System.out.println("---");    Constructor<?> con3 = c.getDeclaredConstructor(String.class, int.class);    con3.setAccessible(true);    Object obj3 = con3.newInstance("张学友", 50);    System.out.println(obj3);//Person [name=张学友, age=50, address=null]}

}

3.通过反射获取对象并使用对象
3.1步骤
获得字节文件对象--通过字节码文件对象创建对象--通过字节码文件对象获得所需结构体,成员变量,成员方法--设置是否允许对成员进行操作的开关--设置对象(如果有需要的话)
3.2用到的方法
public Constructor[] getConstructors() 获取公共的构造方法
public Constructor[] getDeclaredConstructors() 获取所有的构造方法(包括私有)
public Constructor getConstructor(Class... parameterTypes)
public T newInstance(Object... initargs)
public Field[] getFields()获取公有的成员变量
public Field[] getDeclaredFields()获取全部的成员变量,包括私有
public Field getDeclaredField(String name)传入变量名称返回指定的成员变量对象,包括私有
public Field getField(String name)传入变量名称返回指定的成员变量对象,仅可获取共有的
public void set(Object obj,Object value)给一个对象的一个字段设置值
public Method[] getMethods()获取所有公共成员方法
public Method[] getDeclaredMethods()获取所有成员方法,包括私有
public Method getMethod(String name, Class<?>... parameterTypes)
public Method getDeclaredMethod(String name,Class<?>... paameter)
Object invoke(Object obj, Object... args) 让某一个对象使用这个方法,并且传入参数
相关实现代码:

import java.lang.reflect.Constructor;

        public class ConstructorDemo {public static void main(String[] args) throws Exception {    Class<?> c = Class.forName("com.yang_01.Person");    Constructor<?>[] cons = c.getConstructors();    for (Constructor<?> con : cons) {        System.out.println(con);//public com.yang_o1.Person()    }    System.out.println("---");    Constructor<?>[] cons2 = c.getDeclaredConstructors();    for (Constructor<?> con : cons2) {        System.out.println(con);//所有声明的构造方法    }    System.out.println("---");    Constructor<?> con = c.getConstructor();    System.out.println(con);//public com.yang_o1.Person()    Object obj = con.newInstance();    System.out.println(obj);    System.out.println("---");    Constructor<?>[] con1 = c.getDeclaredConstructors();    for (Constructor<?> conse : con1) {        System.out.println(conse);    }    System.out.println("---");    Constructor<?> con2 = c.getDeclaredConstructor(String.class,int.class,String.class);    con2.setAccessible(true);    Object obj2 = con2.newInstance("陈奕迅", 45, "香港");    System.out.println(obj2);//Person [name=陈奕迅, age=45, address=香港]    System.out.println("---");    Constructor<?> con3 = c.getDeclaredConstructor(String.class, int.class);    con3. = con3.newInstance("张学友", 50);    System.out.println(obj3);//Person [name=张学友, age=50,address=null]}

}`