获取String中的byte数组,使用反射的方式(JDK8)

3 篇文章 0 订阅

正常new对象的方式,是由类到对象的形式,类加载-链接-初始化后,对象根据类的模板进行创建。而反射是由对象到模板类的形式,通过对象反向获取Class类信息,然后通过Class模板类获取类中的信息(属性,方法,父类等等Class类信息)。

1.获取String中的Byte数组

		String str = "abcdefg";
        Class aclass = str.getClass(); //获取类信息
        Field value = aclass.getDeclaredField("value"); //获取私有
        value.setAccessible(true);
        char[] arr = (char[]) value.get(str);
        for(char item:arr){
            System.out.print(item);
        }

获取到String的类信息后,由于内部的value数组是由private修饰的私有属性,所有调用getDeclaredField方法能将类中的所有属性拿到。
获取到Field字段后,这里要对私有属性进行读取(get)或修改(set),需要先调用setAccessible方法传入true表明可访问私有属性。
在这里插入图片描述
根据类中字段的名字和修饰符调用Class中相应的方法可获取到类中所有的信息!

2. 浅看下源码

在这里插入图片描述
到JVM中继续看:

JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass, jboolean publicOnly))
{
  JVMWrapper("JVM_GetClassDeclaredFields");
  JvmtiVMObjectAllocEventCollector oam;

  // Exclude primitive types and array types
  if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) ||
      java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->oop_is_array()) {
    // Return empty array..从class模板中读取Field类返回
    oop res = oopFactory::new_objArray(SystemDictionary::reflect_Field_klass(), 0, CHECK_NULL); 
    return (jobjectArray) JNIHandles::make_local(env, res);
  }

再探SystemDictionary::reflect_Field_klass():

do_klass(reflect_Field_klass, java_lang_reflect_Field, Pre )

大致流程为:根据JavaClass对象读取SystemDictionary系统字典中Field的Klass对象,再转为Java的Class对象返回即可。

3.后言

反射的核心-Class对象,作为对象的模版定义存在的对象,编译器限定语法规则:不允许在类外进行变量函数的声明 一切皆类。jvm虚拟机手册提出字节码文件的格式,再由类加载机制通过system Dictionary执行parseClassFile读取字节码文件返回Klass对象,再将其转换为Java的Class对象进行返回,经过初始化后一个Class对象就创建完了,运行时以Class对象为模版new对象,这就是java的一切皆对象 连java的lambda表达式走的都是内部类。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值