反射

反射是架构设计的灵魂
反射的其中一个作用就是强制在内存中创建某个类或接口的java.lang.Class对象(反向加载类)
使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码)

反射的概述
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有的属性和方法;对于任意一个对象,都能够调用他的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。要想解剖一个类,必须先要获取该类的字节码文件对象。而解剖使用的就是Class类中的方法,所以先要获取每一个字节码文件对应的Class类型的对象。

反射就是把Java类中的各种成分映射成一个个的Java对象
例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。(其实:一个类中这些成员方法、构造方法、在加入类中都有一个类来描述)
加载的时候:Class对象的由来是将class文件读入内存,并为之创建一个Class对象
在这里插入图片描述
查看Class类在Java中的api详解
在这里插入图片描述
Class类的实例表示正在运行的Java应用程序中的类和接口,也就是JVM中有N多的实例每个类都有该Class对象(包括基本数据类型)
Class没有公共构造方法。Class对象是在类加载时由Java虚拟机以及通过调用类加载器中的defineClass方法自动构造的,也就是这不需要我们自己去处理创建,JVM已经帮我创建好了。

反射的使用
获取Class对象的三种方式
1、 ObjectgetClass();返回一个对象的运行时类
2、 任何数据类型(包括基本数据类型)都有一个“静态的class属性
3、 通过Class的静态方法:forName(String className)”
其中1是因为Object类中的getClass方法,因为所有类都继承Object类,从而调用Object类来获取: Class stuClass = stu1.getClass();//获取Class对象
第二种方式:Class stuClass2=Student.class;
第三种方式:Class stuClass3=Class.forName(“包名.类名”); //注意此字符串必须时真实路径,就是带包名的类路径,包名.类名
在运行期间,一个类只由一个Class对象产生

通过反射获取构造方法并使用
通过Class对象可以获取某个类中的:构造方法、成员变量、成员方法;并访问成员
1、 获取构造方法
1)、批量的方法:

Public Constructor[] getConstructor():所有“公有的“构造方法
Public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)
2)、获取单个方法、并调用
Public Constructor getConstructor(Class… parameterTypes):获取单个的“公有的”构造方法
Public Constructor getDeclaredConstructor(Class…parameter):获取“某个构造方法”可以是私有的、或受保护、默认、公有;

调用构造方法:Constructor newInstance(Object…initargs)

newInstance是Constructor类的方法(管理构造函数的类)
api的解释为:
newInstance(Object…initarg )

例如:

Class clazz=Class.forName(“包名.Student”);//调用forName将导致Student的类被初始化
Constructor con=clazz.getConstructor(null);//因为是无参的构造方法所以类型是一个null,不写也可以:这里需要的是一个参数的类型   返回的是描述这个公有的无参构造函数的类对象
Object obj= con.newInstance();//以con的构造方法创建一个obj对象

也可以是Object obj=clazz.getConstructor(null).newInstance();

Clazz.getDeclaredConstructor(char.class).setAccessible(true);//暴力访问
Object obj=clazz.getDeclaredConstructor(char.class).newInstance(‘s’);调用私有含char参数的构造方法

获取成员变量并调用
1、 批量的获取:

  1. Field[] getFields();获取所有的“公有字段”
  2. Field[] getDeclaredFields():获取所有字段,包括:私有、受保护、默认、公有
    2、 获取单个的
    1) Field getField(String fielsName):获取某个“公有的”字段
    2) Field getDeclaredField(String fieldName):获取某个字段(可以是私有的)

获取字段的值:

	Field public void set(Object obj,Object value);
		参数说明:
1.	Obj:要设置的字段所在的对象(要传入设置的对象)
2.	Value:要为字段设置的值(要传入实参)
Field f=stuClass.getField(“name”);
Object obj=stuClass.getConstructor().newInstance();//产生Student对象Student stu=new Student();
f.set(obj,”asd”);
Student stu=(Student)obj;
Sout(stu.name);

获取成员方法并调用
1、 批量的:
a) Method[] getMethods():获取所有“公有方法”(包含父类的方法也包括Object类)
b) Method[] getDeclaredMetgods():获取所有的成员方法,包括私有的(不包括继承的)
2、 获取单个的:
a) Method getMethod(String name,Class<?>…parameterTypes)
参数:
Name:方法名
Class…:形参的Class类型对象
b) 调用方法:

Method public Object invoke(Object obj,Object…args):
		参数说明:
			Obj:要调用方法的对象;
			Arg:调用方式时所传递的实参
Mthod m=stuClass.getDeclaredMethod(“show1”,String.class);//获取show1的方法,并把它存放发哦m中
Object obj=stuClass.getConstructor().newInstance();//创建一个Student对象
m.invoke(obj,”asd”);//通过m对obj对象中的show1进行参数传递

通过反射运行配置文件内容

//Properties类用于读取配置文件的键值对
Properties p=new Properties();
FileReader fr=new FileReader(“a.txt”);
p.load(fr);
//通过键获得a.txt的值
String className=p.getProperty(“className”);
String methodName=p.getProperty(“methodName”);
//获取Class字节码文件的对象
Class clazz=Class.forName(className);
//创建一个对象
Object obj=clazz.getConstructor().newInstance();
//获取方法
Method m=clazz.getDeclaredMethod(methodName);
//通过obj调用方法
m.invoke(obj);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值