反射的介绍

### 1.  什么是反射

> ​ JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制

>

> ​ 要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象

>

> ​ 总之,反射就是把java类中的各种成分映射成一个个的Java对象。例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象

### 2. 常用API

> Class类:反射的核心类,反射所有的操作都是围绕该类来生成的,通过它,可以获取类的属性,方法等内容;

> Field类:表示类的属性,可以获取和设置类中属性的值

> Method类:表示类的方法,它可以用来获取类中方法的信息,或者执行方法

> Constructor类:表示类的构造方法

### 3. 反射的应用

#### 3.1 获取Class对象

> ​ 要想使用反射,必须先获取到对应的Class类型的对象;所有的反射都指向一个类:java.lang.Class.这里有三种方式可以得到:

>

> a.通过现有的对象来获取:

>

> ​ Class cls = master.getClass();//这里的master是一个现有的对象

>

> b.通过现有的类来获取:

>

> ​ Class cls = Master.class;//Master是一个现有的能够拿到的类

>

> c.通过字符串,来得到Class对象,这种方式是我们使用最广泛的一种方式,如Hibernate,mybatis的映射文件

>

> ​ Class cls = Class.forName("cn.sz.gl.pojo.Master");//双引号中是Master类的  包.类名

#### 3.2 根据Class创建对象

> a.调用无参构造,来获得对象

>

> ​ Master master = (Master) cls.newInstance();//此时要求Master类中必须有无参构造可以调用

>

> b.先获得指定的构造,然后利用这个构造方法,来获得对象

>

> ​ //得到指定的构造方法,如果有多个参数,中间用","隔开

>

> ​        Constructorcon = cls.getDeclaredConstructor(String.class,Integer.class);

>

> ​ Object obj = con.newInstance("abc",1);

>

> ​ 注意:当没有无参构造,或者无参构造为private修饰的时候,我们不能够再使用newinstance的方式来实例化了。这时候,我们只能先获取指定构造,然后再来实例化

#### 3.3 获得构造方法

> ```java

> //获得所有的构造方法,private修饰的构造不能获得

> Constructor[] cons = cls.getConstructors();

> for(int i=0;i<cons.length;i++){

>   System.out.println(cons[i]);

> }

> ```

>

> 也可以用来获取本类中的所有构造方法,包括private修饰的构造方法:

>

> ```java

> //获得本类所有的构造方法,包括private修饰的构造

> Constructor[] cons = cls.getDeclaredConstructors();

> for(int i=0;i<cons.length;i++){

>   System.out.println(cons[i]);

> }

> ```

>

> 还可以得到指定的某一个构造方法:

>

> ```java

> //得到指定的构造 方法,如果有多个参数,中间用","隔开

> Constructor con =  cls.getDeclaredConstructor(String.class,Integer.class);

> //也可以使用另一种方式来获得:cls.getConstructor(parameterTypes)

> ```

>

>

#### 3.4 获取其他方法

> 获取所有方法,包括继承自父类的方法,但私有方法不能获取:

>

> ```java

> //获得所有的方法,包括继承自父类的方法,但只能是public 修饰的方法

> Method[] ms =  cls.getMethods();

> for(int i=0;i<ms.length;i++){

>   System.out.println(ms[i]);

> }

> ```

>

> 要想获取所有方法,包括私有方法,可以如下(但继承的方法不能得到):

>

> ```java

> //获得本类所有的方法,不包括继承自父类的方法,但private 修饰的方法也能获得

> Method[] ms =  cls.getDeclaredMethods();

> for(int i=0;i<ms.length;i++){

>   System.out.println(ms[i]);

> }

> ```

>

> 也可以获取某一个指定的方法,如下:

>

> ```java

> //获得指定方法(无参)

> Method ms =  cls.getDeclaredMethod("show");

> System.out.println(ms);

> //获得指定方法(有参)

> Method ms =  cls.getMethod("print", String.class);

> System.out.println(ms);

> ```

>

> 此时获得的方法,如果为private修饰,在调用该方法之前,需要先解除封装:

>

> ​ ms.setAccessible(true);

>

> 在获取方法后,要想调用,如下:

>

> ```java

> //通过invoke调用方法,obj表示在哪个对象里调用方法,后续的参数都是方法的传入的参数

> String str = (String) ms.invoke(obj, "测试有参方法");

> System.out.println("方法执行的结果:"+str);

> ```

>

>

#### 3.5 获取属性

> 获取所有属性,包括继承自父类的属性,但不能得到private修饰的属性:

>

> ```java

> //获得所有的public修饰的属性(继承自父类的属性也能获得),private修饰的属性不能获得

> Field [] fs = cls.getFields();

> for(int i=0;i<fs.length;i++){

>   System.out.println(fs[i]);

> }

> ```

>

> 要想获得所有私有属性:

>

> ```java

> //获得本类所有的属性(继承自父类的属性不能获得),private修饰的属性也能获得

> Field [] fs = cls.getDeclaredFields();

> for(int i=0;i<fs.length;i++){

>   System.out.println(fs[i]);

> }

> ```

>

> 也可以获得某个指定的属性:

>

> ```java

> //获得指定的属性

> Field f = cls.getDeclaredField("mastername");

> //mastername属性为私有的,所以要先解除封装

> f.setAccessible(true);

> System.out.println(f.get(obj));

>

>

> //修改指定的属性

> Field f = cls.getDeclaredField("mastername");

> f.setAccessible(true);

> f.set(obj, "lisi");

> System.out.println(f.get(obj));

> ```

>

>

#### 3.6 其他方法

> String getName()  

>

> ​ //获取全限定名(完整包名+类名)

>

> Class [] getInterfaces()  

>   //确定此对象所表示的类或接口实现的接口

>

> Class  getSuperclass()  

>   //返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的超类的 Class

>

> Field类的方法:

>

> ​ String getName()

> ​     获取字段名

> ​ int getModifiers()

> ​     用于返回Field的修饰符

> ​ void setAccessible(true);

> ​     设置该属性能否被访问,如果属性为private,必须设置为true才能访问

> ​ void set(Object obj, Object value)

> ​     将指定对象obj上此 Field 对象表示的字段设置为指定的新值value。

>

> Method类的方法:

>

> ​ String getName()

> ​     获取方法名

> ​ int getModifiers()

> ​     用于返回Method的修饰符

> ​ Class getReturnType()

> ​     获取返回值类型

> ​ Class [] getExceptionTypes()

> ​     获取声明抛出的异常类型

> ​ Class [] getParameterTypes()

> ​     返回方法中各个参数的类型        

>

> Constructor类的方法:

>

> ​ int getModifiers()

> ​     用于返回Method的修饰符

> ​ Class [] getExceptionTypes()

> ​     获取声明抛出的异常类型

> ​ Class [] getParameterTypes()

> ​     返回方法中各个参数的类型


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值