首页 > 其他分享 >关于一些反射的基本认识吧

关于一些反射的基本认识吧

时间:2022-12-01 18:12:48浏览次数:35  
标签:反射 String 认识 public 获取 关于 返回值 Class name

反射

框架设计的灵魂

## 什么是框架?

 

半成品软件
可以在框架的基础上进行软件的开发,简化编码

其实如果自己学框架并不需要框架,但如果以后要自己写框架,则需要对反射理解特别深!

 

反射的概念

将类的各个组成部分封装为其他对象,这就是反射机制

先说一说java代码运行的三个步骤

### 1,编码阶段

这个时候还是硬盘上,没有进入虚拟机

 

名字叫Junit.java的文件的代码如下:

public class Junit {    
    //属性
    private String name;
    private String a1;
​
    //构造方法
    public Junit(String name, String a1) {
        this.name = name;
        this.a1 = a1;
    }
    public Junit() {
    }
​
    //普通方法   
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
 }

 

然后通过javac编译后

变成Junit.class的二进制字节码文件,

 private String name;
 private String a1;
public Junit(String name, String a1) {
        this.name = name;
        this.a1 = a1;
    }
public Junit() {
    }
 public String getName() {
        return name;
    }
 public void setName(String name) {
        this.name = name;
    }

 

就会分为三个部分

 

然后进入第二阶段

2,将字节码文件加载进内存

使用的是类加载器

对应的java里面的一个对象,叫作ClassLoader

在java里面有一个Class类(名字叫Class的类)

可以用来描述字节码文件的共同的行为!

 

在上面我把字节码文件写成了三个部分,这三个部分就是字节码文件的三个共同部分

1,三个成员变量(类里面的属性)

2,构造方法

3,成员方法

在Class类里面,把成员变量用:Field数组描述 fields

构造方法用:Constructor数组描述 constructors

成员方法:Method数组描述 methods

 

3,创建对象运行阶段

 

反射的好处

1,可以在程序运行过程中,可以操作这些对象

2,可以解耦,降低程序的耦合性,提高程序的可扩展性

 

获取Class对象(字节码对象)的方式

有三种方式,分别对象java代码的三个阶段

1,Class.forName("全类名")
全类名就是包名加类名

将字节码文件加载进内存,生成Class对象

Class c1=Class.forName("com.java1201.xiawu.ceshi.Ren");
因为使用的是全类名,所以需要用字符串,一般多用于配置文件。

将类名定义在配置文件中,通过读取配置文件,然后用反射创建字节码对象。

避免重复使用!

 

2,类名.class 类默认的class属性
通过类名属性获取Class对象

Class c2 = Ren.class;
多用于参数的传递

 

3,对象.getclass()
通过方法获取Class对象

 Class c3=new Ren().getClass();
多用于对象调取字节码文件

 

通过这三种方式获取的字节码对象都是一个

        Class c1=Class.forName("com.java1201.xiawu.ceshi.Ren");
         Class c2 = Ren.class;
         Class c3=new Ren().getClass();
         System.out.println(c1==c2&&c2==c3);
         
 控制台运行结果:
    ture

 

 

Class对象(字节码对象)的使用

 1,获取成员变量们
​
```
方法:
    获取public修饰和父类继承来的成员变量:getFields()  返回值 Field[]
    获取指定public修饰和父类继承来的成员变量:getFiled(String name) 返回值 Field
    
    获取所有的成员变量:getDeclaredFields()  返回值 Field[]
    获取指定的成员变量:getDeclaredField(String name)  返回值 Field
    
    如果找不到指定的成员变量会抛出一个空异常
```

 



 2,获取构造方法们
​
其实和上面成员变量的方法差不多
​
```
方法:
    获取public修饰和父类继承来的构造方法:getConstructors()  返回值 Constructor<?>[]
    获取指定public修饰和父类继承来的构造方法:getConstructor(String name) 返回值 Constructor<?>
    
    获取所有的构造方法:getDeclaredConstructors()  返回值 Constructor<?>[]
    获取指定的构造方法:getDeclaredConstructor(String name)  返回值 Constructor<?>
    
    如果找不到指定的成员变量会抛出一个空异常
```

 



 3,获取成员方法们
​
```
方法:
    获取public修饰和父类继承来的成员方法:getMethod 返回值 Constructor<?>[]
    获取指定public修饰和父类继承来的成员方法:getMethods(String name, Class<?>... parameterTypes) 返回值 Method
    
    获取所有的成员方法:getDeclaredMethods()  返回值 Method[]
    获取指定的成员方法:getDeclaredMethod(String name,Class<?>... parameterTypes)  返回值 Method
```

 




4,获取类名
​
•   获取类名: getName  返回值 String
​
•   获取包名: getPackage() 返回值 Package

 



 Class c2 = Ren.class;
Field f=c2.getField("a2"); //获取指定的声明的属性对象

Ren r=(Ren) c2.getDeclaredConstructor().newInstance(); //获取一个操作对象,这里是用了获取字节码对象无参构造的一个方法,用来创建新的对象

赋值成员变量:set(Object obj, Object value) ,  前面这个obj是对象,后面的是需要赋入的值
        f.set(r,"zp");    //给,r对象,的f属性,赋值"zp"
获取成员变量的值
        f.get(r);       //获取,r对象的f属性值,
        
调用无参成员方法:invoke(Object obj, Object... args)   返回值:Object
​
         Method m1=c2.getMethod("getNme") //获取指定的声明的成员对象
         m1.invoke(r);
调用有参且只有一个参数的成员方法:
        Method m2=c2.getMethod("setNme",方法参数类型.Class);  //大基本类型的话,要用对应的包装类型
        m1.invoke(r,值);
调用多个参数的成员方法:
        Method m3=c2.getMethod("add",方法参数类型.Class,方法参数类型.Class…………)  //有几个参数写几个
        m1.invoke(r,值,值…………);
        
 构造方法那个和成员方法类似,

 

 
上面的方法,对私有属性都是没办法操作的
想操作私有犯法或属性,可以用暴力反射
使用方法:
获取的对象.setAccessible(true);
这个获取的对象指的是Method,Field这些

 

 

标签:反射,String,认识,public,获取,关于,返回值,Class,name
From: https://www.cnblogs.com/fssnjcl/p/16942229.html

相关文章

  • SpringSecurity OAuth2 关于 UserAuthenticationConverter
    前言之前写了一大堆关于SpringSecurityOAuth2的相关文章,本以为可以告一段落了,但是有了解到一个新东西,之前没注意到的,就是UserAuthenticationConverter,本章就来看看这是......
  • <三>关于对象优化
    代码1#include<iostream>usingnamespacestd;classMyString3{public: MyString3(constchar*pChar=nullptr){ if(pChar==nullptr){ this->pString......
  • 关于粉丝迁移至本公众号的说明
    感谢您继续关注我们的公众号。您之前关注的公众号元宇宙之心MetaverseHub已经将全部业务、功能转移至本公众号。迁移详情如下:旧帐号名称:元宇宙之心MetaverseHub旧帐号主体:熵......
  • 关于c++的预定义宏
    有时候看到代码里充斥着宏,很难受,这些宏都是啥玩意,哪来的。有些是库或者代码定义的,有些是编译器定义的,有些是cmake里面定义的,再在代码里使用。查看或者说查询语言标准,编译器......
  • 关于字节大小端
    来自libhv的检验字节大小端的方法https://github.com/ithewei/libhv/blob/master/base/hendian.hstaticinlineintdetect_endian(){union{charc;......
  • 关于账本的数据一致性较好的解决思路
    账本中采用申请单制1.每笔进出账订单都先生成一笔申请单记录金额,进出款类型,2.默认状态未开始,当资金已经消费或者最终返款完成时,申请单完结3.每天执行定时任务对上一......
  • 关于迭代Iterator
    List<ReplenishmentReportVO>missingStockProducts=NewArrayLIst<>;Iterator<ReplenishmentReportVO>itreator=missingStockProducts.iterator();while(itreator.hasNe......
  • 关于 find 命令的15个超级有用的例子
    find 命令用于在Linux命令行中搜索文件和目录。find是功能最强大、使用最频繁的命令之一,同时也是选项最多的命令之一,它有50多个选项,很容易让人弄混了,特别是当它与exec......
  • 关于vm虚拟机网络设置的思考
    问题背景:实验环境要求四台电脑,hostIP如下client:  eth0192.168.4.10/24proxy:  eth0192.168.4.5/24      eth1192.168.2.5/24web1:  eth0192.1......
  • Java进阶学习之反射与动态绑定(5)
    目录1.反射1.1.概述1.2.实现方式1.2.1.获取Class1.2.2.通过反射获取属性、设置属性1.2.3.通过反射获取方法、执行方法1.2.4.通过反射获取构造器并调用2.动态代理2.1.代理模......