【无标题】Java反射

1、反射

1.1、介绍

  • Reflection(反射)是Java语言的特征之一
  • 允许运行中的Java程序对自身进行检查
  • 反射能够直接操作类私有属性
  • 反射能够在运行的时候获取一个类中的所有信息(成员变量、方法、构造器等)。

​ 要想剖析一个类,必须先要获取该类的字节码对象(class对象),而剖析就是使用Class类中的方法。即,反射就是把Java类中的各个成分(变量、方法等等)映射成一个个的Java对象,

// 常用方法
//获取包名、类名
clazz.getPackage().getName()//包名
clazz.getSimpleName()//类名
clazz.getName()//完整类名
 
//获取成员变量定义信息
getFields()//获取所有公开的成员变量,包括继承变量
getDeclaredFields()//获取本类定义的成员变量,包括私有,但不包括继承的变量
getField(变量名)
getDeclaredField(变量名)
 
//获取构造方法定义信息
getConstructor(参数类型列表)//获取公开的构造方法
getConstructors()//获取所有的公开的构造方法
getDeclaredConstructors()//获取所有的构造方法,包括私有
getDeclaredConstructor(int.class,String.class)
 
//获取方法定义信息
getMethods()//获取所有可见的方法,包括继承的方法
getMethod(方法名,参数类型列表)
getDeclaredMethods()//获取本类定义的的方法,包括私有,不包括继承的方法
getDeclaredMethod(方法名,int.class,String.class)
 
//反射新建实例
clazz.newInstance();//执行无参构造创建对象
clazz.newInstance(222,"韦小宝");//执行有参构造创建对象
clazz.getConstructor(int.class,String.class)//获取构造方法
 
//反射调用成员变量
clazz.getDeclaredField(变量名);//获取变量
clazz.setAccessible(true);//使私有成员允许访问
f.set(实例,);//为指定实例的变量赋值,静态变量,第一参数给null
f.get(实例);//访问指定实例变量的值,静态变量,第一参数给null
 
//反射调用成员方法
Method m = Clazz.getDeclaredMethod(方法名,参数类型列表);
m.setAccessible(true);//使私有方法允许被调用
m.invoke(实例,参数数据);//让指定实例来执行该方法

测试:

public class UserTest {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        Class<?> c1 = Class.forName("com.psy.fanshe.User");
      	// 生成无参的对象
        Object user = c1.newInstance();
        System.out.println(user);

        /**
         * 获取class的三种方式(一个Class只有一个class对象)
         * 以下最常用的是第三种,第一种对象都有了,就不需要反射了。第二种需要导入包,不导入包就无法使用,不够灵活。第三种是最安全的,性能最好的
         * 1、对象.getClass()
         * 2、类.class
         * 3、Class.forName("全类名")
         */
        // 1、对象.getClass()
        User user1 = new User();
        Class c2 = user1.getClass();
        // 2、类.class
        Class c3 = User.class;
       // 查看是否是同一个hashcode用来判断是否是同一个对象
        System.out.println(c1.hashCode()+" "+c2.hashCode()+" "+c3.hashCode());
    }
}

1.2、类加载时候的内存分析

Java内存:

    • 存放new的对象和数组
    • 可以被所有的线程共享,不会存在别的对象引用。
    • 一些要执行的代码
    • 存放基本变量类型
    • 由方法区中的class信息创建的java.lang.Class对象
  • 方法区(特殊的堆)
    • 可以被所有的线程共享
    • 包含了所有的class的信息和static变量

类加载时候的内存分析:

当那个程序主动使用某个类时,如果该类还未加载到内存中,则系统会通过如下三个步骤对该类进行初始化。

  • 类的加载

​ 将类的class文件读入内存。此过程由类的加载器完成,并将静态数据装换成方法区的运行时数据,并为之创建一个java.lang.Class对象

  • 类的链接

​ 将类的二进制数据合并到JRE中,为类变量(static)分配内存,并设置默认的初始值,内存在方法区中进行分配

  • 类的初始化

​ JVM负责对类进行初始化

什么时候会发生类的初始化:

  • 类的主动引用
    • 当虚拟机被启动,先初始化main方法所在的类
    • new一个类的对象
    • 调用类的静态成员和静态方法
    • 使用java.lang.reflect包对类进行反射调用
    • 初始化一个类,其父类没有被初始化的时候,首先初始化其父类
  • 类的被动引用(不会发生类的初始化)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值