java反射

java反射(概念)

反射的一些概述:

—什么是反射机制:

​ 反射机制是java动态性之一,而说到动态性首先得了解动态语言。那么何为动态语言

–什么是动态语言

​ 是指程序在运行时可以改变其结构:新的函数可以引进,已有的函数可以被删除等结构上的变化。比如常见的javaScript就是动态语言,除此之外Ruby,python等也属于动态语言,而c、c++则不属于动态语言。

–java是动态语言吗

​ 从动态语言能在运行时改变程序结构或则变量上看,Java和c、c++一样都不属于动态语言。但是java却又有一个非常突出的与动态相关的机制:反射机制。java通过反射机制,可以在程序运行时加载,探知和使用编译期间完全未知的类,并且可以生成相关类对象实例,从而可以调用其方法或则改变某个属性值。所有Java也可以算得上是一个半动态的语言

–什么是反射机制

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

一句话概述:反射就是把java类中的各种成分映射成一个个的Java对象

反射的应用场合
	在编译时根本无法知道该对象或类可能属于哪些类,程序只依靠运行时信 

​ 息来发现该对象和类的真实信息

反射的作用

​ 通过反射可以使程序代码访问装载到JVM 中的类的内部信息

	获取已装载类的属性信息 

​ 获取已装载类的方法

​ 获取已装载类的构造方法信息

反射技术的引入

​ 在JDK中,主要由以下类来实现Java反射机制,这些类都位于

​ java.lang.reflect 包中

Class类:代表一个类

Field 类:代表类的成员变量(属性)

Method类:代表类的成员方法

Constructor 类:代表类的构造方法

Array类:提供了动态创建数组,以及访问数组的元素的静态方法

反射技术的入口类Class
  • Class类是Java 反射机制的起源和入口

​ 用于获取与类相关的各种信息

​ 提供了获取类信息的相关方法

​ Class类继承自Object类

  • Class类是所有类的共同的图纸

    ​ 每个类有自己的对象,好比图纸和实物的关系

    ​ 每个类也可看做是一个对象,有共同的图纸Class,存放类的结构信息,

    ​ 能够通过相应方法取出相应信息

      		类的名字 
    
      		属性 
    
      		方法 
    

    ​ 构造方法

    ​ 父类和接口

class常用方法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3XLVC94E-1574769376392)(D:\学习文件\博课\img\反射class.png)]

使用反射可以在编译和运行期间动态获取类的信息

1.获取类class对象

​ 获取方式:①、通过类对象获取类的Class

②、通过类的名称、类名.class

③、通过完整路径字符串获取

Class c=Class.forName(“类的路径”);

2.获取类中属性Field

​ ①、获取类中所有public属性

​ Field[] f=Class.getFields();

a.getName(), a.getType().getSimpleName()//取成员类型

–getFields(); //获得所有public属性

–getField(String name);//获得指定public属性

FieldgetDeclaredField(String name) 返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。
Field[]getDeclaredFields() 返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。
3.获取类中方法methods

​ ①、获取类中所有的public的方法、不仅时当前类的,还能获取到所有继承类的public的方法

​ Method m[]=class.getMethods();

–getMethods(); //获得所有public方法

–getMethod(String name,Class[] args);//获得指定public方法

参数传递的是Class类型,基本数据类型的class与它封装类的class是不一样的 例:int.class;

MethodgetDeclaredMethod(String name, Class<?>… parameterTypes) 返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。
Method[]getDeclaredMethods() 返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。

获取方法的参数 Parameter

​ m.getName(); 方法名 m.getReturnType(); 方法返回值 类型

​ Parameter[] p=m.getParameters(); 方法所有参数

4.类的基本信息(包路径Package)

​ ①、Package age=类名.getPackage;

在反射中,java将类中所有的信息都封装成了对象


类–>Class

TnewInstance() 创建此 Class 对象所表示的类的一个新实例。 类似于调用该类的无参构造方法
Field[]getDeclaredFields 返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段
Method[]getDeclaredMethods() 返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
Constructor<T>getConstructor(Class<?>… parameterTypes) 返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。
Constructor<?>[]getConstructors() 返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。

包–>Package

属性–>Field
返回值方法 描述
StringgetName() 返回此 Field 对象表示的字段的名称
Class<?>getType() 返回一个 Class 对象,它标识了此 Field 对象所表示字段的声明类型。 .getSimpleName()//取成员类型

Class.getField(String)方法可以获取类中的指定字段(可见的), 如果是私有的可以用getDeclaedField(“name”)方法获取,通过set(obj, “李四”)方法可以设置指定对象上该字段的值, 如果是私有的需要先调用setAccessible(true)设置访问权限,用获取的指定的字段调用get(obj)可以获取指定对象中该字段的值

方法–>Mothod

Class.getMethod(String, Class…) 和 Class.getDeclaredMethod(String, Class…)方法可以获取类中的指定方法,

如果为私有方法,则需要打开一个权限。setAccessible(true);

用invoke(Object, Object…)可以调用该方法,

跟上面同理,也能一次性获得所有的方法

参数–>Parameter

构造方法–>Constructor
TnewInstance(Object… initargs) 使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。

getConstructor(String.class,int.class)方法获取一个指定的构造函数然后再调用Constructor类的newInstance(“张三”,20)方法创建对象


接口–>interfaces()

​ Class[] getInterfaces():确定此对象所表示的类或接口实现的接口

返回值:接口的字节码文件对象的数组

2.6、获取指定资源的输入流

InputStream getResourceAsStream(String name)

return:一个 InputStream 对象;如果找不到带有该名称的资源,则返回null

参数:所需资源的名称,如果以"/“开始,则绝对资源名为”/"后面的一部分。

​ 2.7、动态代理的概述和实现

动态代理:一种设计模式,其非常简单,很容易理解,你自己可以做这件事,但是觉得自己做非常麻烦或者不方便,所以就叫一个另一个人(代理)来帮你做这个事情,而你就不用管了,这就是动态代理。举个例子,买火车票叫人代买。

在程序运行过程中产生的这个对象,而程序运行过程中产生对象其实就是我们刚才反射讲解的内容,所以,动态代理其实就是通过反射来生成一个代理

在Java中java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口就可以生成动态代理对象。JDK提供的代理只能针对接口做代理。我们有更强大的代理cglib,Proxy类中的方法创建动态代理类对象

分三步,但是注意JDK提供的代理正能针对接口做代理,也就是下面的第二步返回的必须要是一个接口。

1、new出代理对象,通过实现InvacationHandler接口,然后new出代理对象来。

2、通过Proxy类中的静态方法newProxyInstance,来将代理对象假装成那个被代理的对象,也就是如果叫人帮我们代买火车票一样,那个代理就假装成我们自己本人

3、执行方法,代理成功


反射总结(简单运用)

—获取字节码 Class.forname(“包名.文件名”);

–获取构造方法 getConstructor(String.class,int.class)方法获取一个指定的构造函数然后再调用Constructor类的 newInstance(“张三”,20)方法创建对象


0、通过反射创建对象的方式

1、Class对象的newInstances()

2、通过构造函数对象的newInstances()

1、对属性值的操作

Filed对象.getXXX(Object obj) : obj表示当前反射的类的对象

​ .setXXX(Object obj)

2、执行方法操作

通过method对象的invoke(Object obj,Object… param)调用方法

3、Array用于操作数组

创建数组:Array.newInstance(String.class, 3);

往数据里存入数据:Array.set(arr, 0, “100”);

取出指定下标的数据:Array.get(arr0, 1)

ect obj) : obj表示当前反射的类的对象

​ .setXXX(Object obj)

2、执行方法操作

通过method对象的invoke(Object obj,Object… param)调用方法

3、Array用于操作数组

创建数组:Array.newInstance(String.class, 3);

往数据里存入数据:Array.set(arr, 0, “100”);

取出指定下标的数据:Array.get(arr0, 1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值