zoukankan      html  css  js  c++  java
  • 简单使用java反射

    零、类的加载时机&类加载器

    1.类的加载时机

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

    总的来说类的加载时机分为以下几种:

    • 创建类的实例
    • 访问类的静态变量,或者为静态变量赋值
    • 调用类的静态方法
    • 初始化某个类的子类
    • 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象

    2.类加载器

    1.什么是类加载器

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

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

    一、反射

    我们首先知道创建一个对象的三个阶段分为:

    1. 源文件阶段 .java的文件
    2. 字节码阶段 .class
    3. 创建对象阶段 new 对象名称

    那么什么是反射呢?JAVA反射机制就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态用对象的方法的功能称为java语言的反射机制。想要使用反射,就必须得要获取字节码文件

    假设我们有如下一个Person类,我们通过字节码去获取这个类的属性、方法、对象等

    public class Person {
    	public String name;
    	public int age;
    	private String gender;
    	
    	public Person() {
    		super();
    	}
    	public Person(String name, Integer age) {
    		super();
    		this.name = name;
    		this.age = age;
    	}
    	public void show() {
    		System.out.println("姓名 "+ name + "年龄 " + age);
    	}
    	private void eat(String g) {
    		gender = g;
    		System.out.println("性别"+gender);
    	}
    }
    

    1.获取字节码对象

    获取字节码对象有三种方法:

    • Object类的getClass()方法,判断两个对象是否是同一个字节码文件
    • 静态属性class,当作静态方法的锁对象
    • Class类中静态方法forName(),读取配置文件
    public static void main(String[] args) throws Exception {
    		//方法1
    		Class clazz = Class.forName("com.thinmoon.reflect.Person");
    		//方法2
    		Class clazz2 = Person.class;
    		//方法3
    		Person p = new Person();
    		Class clazz3 = p.getClass();
    		
    	}
    

    2.通过字节码创建对象

    1).通过无参构造创建对象
    //1.
    Class clazz = Class.forName("com.thinmoon.reflect.Person");
    Person p = (Person)clazz.newInstance();
    p.age = 1;
    p.name = "ls";
    p.show();
    
    2).通过有参构造创建对象
    //2.
    Class clazz = Class.forName("com.thinmoon.reflect.Person");
    //获取构造器
    Constructor c = clazz.getConstructor(String.class, Integer.class);
    //通过构造器创建对象
    Person p2 = (Person)c.newInstance("lsss", 111);
    p2.show();
    

    3.获取字段

    1).获取公共字段
    //获取公有属性
    Field f = clazz.getField("name");
    f.set(p2, "ssss");
    
    2).获取私有属性
    //获取私有属性
    Field f1 = clazz.getDeclaredField("gender");
    //去除私有权限
    f1.setAccessible(true);
    f1.set(p2, "女");
    

    4.获取方法

    1).获取公共方法
    //获取公共方法
    Method m1 = clazz.getMethod("show");
    m1.invoke(p2);
    
    2).获取私有方法
    //获取私有方法
    Method m2 = clazz.getDeclaredMethod("eat", String.class);
    m2.setAccessible(true);
    m2.invoke(p2, "sssaaaaaaaaa");
    
  • 相关阅读:
    Linux服务器修改时区
    Linux磁盘IO查看
    passwd: 鉴定令牌操作错误
    Kubernetes 使用Nginx-Ingress实现蓝绿发布/金丝雀发布/AB测试【转】
    MySQL count 浅析【转】
    k8s pv,pvc无法删除问题【转】
    K8S 上部署 Redis-cluster 三主三从 集群【转】
    XtraBackup 备份加速【转】
    Gitlab+DRBD 高可用方案【转】
    Linux网卡bond的七种模式详解【转】
  • 原文地址:https://www.cnblogs.com/ThinMoon/p/12368036.html
Copyright © 2011-2022 走看看