反射基础入门

反射

反射机制

反射快速入门

利用反射机制加载配置文件实现对象实例化,并调用方法
package com.czl.re;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

/**
 * @author CaoZiLiang
 * @date 2022/9/8 11:53
 */
public class Demo {
    public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {


        Properties properties = new Properties();
        properties.load(new FileInputStream("src/main/resources/re.properties"));
        String classfullpath = properties.getProperty("classfullpath");
        String method1 = properties.getProperty("method");
        
        //利用反射机制加载配置文件实现对象实例化,并调用方法
        //(1) 加载类 , 返回Class 类型的对象cls
        Class cls = Class.forName(classfullpath);
        //(2)通过cls 得到加载的类的对象实例
        Object o = cls.nwInstance();
        System.out.println(o.getClass());//运行对象
        //(3) 可以通过cls的到加载的类的方法名为(cry)的方法对象
        //在反射中,可以把方法视为对象
        Method cry = cls.getMethod(method1);
        //(4)通过方法对象来调用方法
        cry.invoke(o);  //传统 对象.方法()  反射机制 方法.invoke(对象)
    }
}
re.properties
classfullpath=com.czl.re.Cat
method=cry
package com.czl.re;



/**
 * @author CaoZiLiang
 * @date 2022/9/9 15:05
 */
public class Cat {
    private String name = "招财猫";
    public void cry(){
        System.out.println("hi"+name);
    }
}
运行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zwfEe77h-1664163338072)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20220909152249833.png)]

java程序在计算机三阶段

代码阶段/编译阶段 —》javac编译得到 .class 字节码文件

Class类阶段(加载阶段)

Runtime运行阶段

new 对象 ,进行类加载,通过类加载器在堆中开辟空间

通过反射得到类成员变量,无参构造器,有参构造器
//得到int字段
//getField 不能得到private属性
Field age = cls.getField("age");
System.out.println(age.get(o)); //传统 对象.成员变量   --》反射: 成员变量对象.get(对象)
//无参构造
Constructor constructor = cls.getConstructor();
System.out.println(constructor);
Constructor constructor1 = cls.getConstructor(String.class);
System.out.println(constructor1);
package com.czl.re;



/**
 * @author CaoZiLiang
 * @date 2022/9/9 15:05
 */
public class Cat {

    private String name = "招财猫";
    public int age = 10;
    public Cat(){}
    public Cat(String name){
        this.name = name;
    }
    public void cry(){
        System.out.println("hi"+name);
    }

}

反射调用优化

​ Method Field Constructor 对象都有setAccessible()方法,启动和禁用访问安全检查的机关,参数为true,取消访问检查,加快效率

Class类

获取Class对象的六种方式

Class.forName(“”)// 多用于配置文件,读取类全路径

类.class //用于参数传递

对象.getClass() // 运行类型 (复习多态)

类加载器 ClassLoader.getClassLoader

类加载

定义:将编译后的字节码文件,通过类加载器,加载到堆,并且生成一个Class对象,并且在方法区生成字节码文件的二进制数据(元数据)
通过反射完成类加载

静态加载:编译时就会加载,如果没有就报错

动态加载:代码执行到才会进行加载,编译时不会加载

类加载时机

(1)new对象时 //静态

(2) 子类被加载,父类也被加载 //静态

(3)调用类中的静态成员时 //静态

(4 )通过反射 //动态

类加载流程

源码 ->编译-> 字节码文件 ->运行-> 类加载{ [加载Loading] >>> [连接linking(验证、准备、解析)] >>> [初始化initialization] }

类加载五个阶段分析
1 加载阶段

(1)JVM在该阶段的主要目的是将字节码从不同的数据源(class文件,jar包,或网络等等)转化为二进制字节流加载到内存中,并乘胜一个代表该类的Java.lang.Class对象

2 连接 -验证

(1)确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全

(2)可以考虑使用**-Xverify:none** 参数来关闭大部分的类验证措施,缩短虚拟机类加载的时间

3 连接 -准备

(1)JVM会在该阶段对类变量,分配内存并默认初始化(是初始化,只分配内存,不赋值

例子:

public int n= 10; //实例类型,不会分配内存

public static int n = 10; // 类变量 分配内存并初始化为 0 ,不是20

public static final int n = 10; // 常量 赋值就不变 n=10

4连接 -解析

(1)虚拟机将常量池内的符号引用替换为直接引用过程 即

5初始化

(1) 开始执行类中定义的java程序代码,执行()方法的过程

(2)() 编译器按语句在源文件中出现的顺序,一次自动收集类中的所有静态变量的赋值和静态代码块中的语句,并进行合并

(3) 虚拟机会保证一个类的()方法在多线程坏境中被正确的加锁,同步,如果多个线程同时去初始化一个类,那么只会有一个线程去执行这个类的()方法,其他线程都去要阻塞等待,直到活动线程执行()方法完毕

()方法的过程

(2)() 编译器按语句在源文件中出现的顺序,一次自动收集类中的所有静态变量的赋值和静态代码块中的语句,并进行合并

(3) 虚拟机会保证一个类的()方法在多线程坏境中被正确的加锁,同步,如果多个线程同时去初始化一个类,那么只会有一个线程去执行这个类的()方法,其他线程都去要阻塞等待,直到活动线程执行()方法完毕

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值