22heima-02进阶-day18 类加载器,反射

类加载器负责将.class文件(存储的物理文件)加载到内存中
类加载时机:
①创建类的实例(对象)
②调用类的类方法
③访问类或接口的类变量,或者为该类变量赋值
④使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
⑤初始化某个类的子类
⑥直接使用java.exe命令来运行某个主类

类加载的流程:
1.加载
①通过一个类的全限定名来获取定义此类的二进制字节流
②在这个字节流所代表的的静态存储结构转化为运行时数据结构
③在内存中生成一个代表这个类的java.lang.Class对象,任何类被使用时,系统都会为之建立java.lang.Class对象
2.验证:链接阶段的第一步,为了确保Class文件字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身安全
3.准备:负责为类的类变量(被static修饰的变量)分配内存,并设置默认初始化值
4.解析:将类的二进制数据流中的符号引用替换为直接引用
5.初始化:根据程序员通过程序制定的主观计划去初始化类变量和其他资源

类加载器的分类
启动类加载器:虚拟机内置的类加载器
平台类加载器:负责加载JDK中的一些特殊模块
系统类加载器:负责加载用户类路径上所指定的类库

day18-08 反射

反射机制:
是在运行状态中,对于任意一个类,都能知道这个类的所有属性和方法。对于任意一个对象,都能够调用它的任意属性和方法。这种动态获取信息以及动态调用对象方法的功能成为Java语言的反射机制。
利用反射调用它类中的属性和方法时,无视修饰符

reflectDemo.java

public class ReflectDemo1 {
    public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //获取系统加载器,加载prop.properties文件
        InputStream is=ClassLoader.getSystemClassLoader().getResourceAsStream("prop.properties");
        //创建Properties集合
        Properties prop = new Properties();
        //将文件中的数据读取到集合当中
        prop.load(is);
        is.close();

        // 下面为利用反射创建对象并调用方法
        //获取字节码文件对象
        Class clazz=Class.forName(prop.getProperty("className"));
        //获取构造器对象
        Constructor constructor = clazz.getConstructor();
        //利用构造器对象创建一个对象
        Object o=constructor.newInstance();
        //获取方法对象
        Method method=clazz.getMethod(prop.getProperty("methodName"));
        //运行方法
        method.invoke(o);
    }
}

prop.properties

className=myreflect.myreflect1.Student
methodName=study

student/teacher/worker是普通javabean
修改反射调用方法只要修改prop.properties里的内容

day18-09 反射 获取class对象

1.Class.forName(“全类名”)
2.类名.class
3.对象.getClass()
获取的对象唯一

// 获取class对象的三种方式
public class ReflectDemo1 {
    public static void main(String[] args) throws ClassNotFoundException {
        //1.Class类中的静态方法forName("全类名")
        //全类名:包名+类名
        Class clazz = Class.forName("myreflect.myreflect2.Student");
        System.out.println(clazz);
        //2.通过class属性获取
        Class clazz2=Student.class;
        System.out.println(clazz2);
        //3.利用对象的getClass方法来获取class对象
        //getClass方法是定义在Object类中
        Student s=new Student();
        Class<? extends Student> clazz3 = s.getClass();
        System.out.println(clazz3);
    }
}

class myreflect.myreflect2.Student
class myreflect.myreflect2.Student
class myreflect.myreflect2.Student

day18-10 反射 获取Constructor对象

在这里插入图片描述

public class ReflectDemo1 {
    public static void main(String[] args) throws ClassNotFoundException {
        //Constructor<?>[] getConstructors():返回所有公共构造方法对象的数组
        //1.获取class对象
        Class clazz = Class.forName("myreflect.myreflect3.Student");
        Constructor[] constructors = clazz.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }
        //Constructor<?>[] getDeclaredConstructors():返回所有构造方法对象的数组(包含public和private)
        //Constructor<?>[] getConstructor(Class<?> ...parameterTypes ):返回单个公共构造方法对象的数组
        //Constructor<?>[] getDeclaredConstructor(Class<?> ...parameterTypes):返回单个构造方法对象的数组
    }
}

day18-11 反射 利用Constructor创建对象

public class ReflectDemo2 {
    //获取Constructor对象并创建对象
    public static void main(String[] args) throws InvocationTargetException, InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException {
        // T newInstance (Object... initargs)"根据指定的构造方法创建对象

        //1.获取class对象
        Class clazz = Class.forName("myreflect.myreflect3.Student");
        //2.获取构造方法对象
        Constructor constructor = clazz.getConstructor(String.class,int.class);
        //3.利用newInstance创建Student的对象
        Student student = (Student) constructor.newInstance("zhangsan",23);
        System.out.println(student);

        //2B.获取空参构造方法对象
        Constructor constructor1 = clazz.getConstructor();
        //3B.利用空参来创建Student对象
        Student student1 = (Student) constructor1.newInstance();
        System.out.println(student1);

        //2C.获取一个私有化的构造方法
        Constructor declaredConstructor = clazz.getDeclaredConstructor(String.class);
        //被private修饰的成员不能直接使用,如果用反射强行获取并使用,需要临时取消访问检查
        declaredConstructor.setAccessible(true);
        //3C.直接创建对象
        Student student2 = (Student) declaredConstructor.newInstance("zhangsan");
        System.out.println(student2);
    }
}

小结
获取class对象
三种方式——Class.forName(“全类名”)
获取里面的构造方法对象
getConstructor(Class<?> ...parameterTypes ) getDeclaredConstructor(Class<?> …parameterTypes)
如果是public的,直接创建对象
newInstance(Object… inieagrgs)
如果是非public,需要临时取消检查,然后再创建对象
setAccessible(boolean) 暴力反射

day18-13 反射 获取Field对象

Field[] getFields():返回所有公共成员变量对象的数组
Field[] getDeclaredFields():返回所有成员变量对象的数组
Field getField(String name):返回单个公共成员变量对象
Field getDeclaredField(String name) :返回单个成员变量对象

void set(Object obj,Object value):给指定对象的成员变量赋值
Object get(Object obj):返回指定对象的Field的值
//1.获取class对象
Class clazz= Class.forName(“myreflect.myreflect3.Student”);
//2.获取name这个成员变量
Field field = clazz.getField(“name”);
//3.利用set方法进行赋值
//3.1创建一个Student对象
Student student = (Student) clazz.newInstance();
//3.2 给指定对象赋值
field.set(student,“zhangsan”);

day18-13 反射 获取Method对象

Method[] getMethods():返回所有公共成员方法对象的数组,包括继承的
Method[] getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的
Method getMethod(String name,Class<?> ...parameterTypes):返回单个公共成员方法对象 Method getDeclaredMethod(String name.Class<?> …parameterTypes) :返回单个成员方法对象

运行:
Object invoke(Object obj,Object…args):运行方法
参数1:用obj对象调用该方法
参数2:调用方法的传递的参数(没有就不写)
返回值:方法的返回值(如果没有就不写)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值