Java基础之反射

今天我们简单的说说java中的反射

反射算是一个比较难理解的知识,但是如果你的面向对象思想很好,那么反射也不难理解

反射就是动态获取类(即字节码文件),并对其成员进行操作,包括对其属性,构造方法以及普通方法的操作

只用一个class文件(字节码文件)就可以实现和new一个对象一样的效果

 

其实反射就是把字节码文件面向对象了,虽然每个类的属性方法都不同,但是它们都有个共性,就是它们都有属性,构造方法,方法,其中,属性为Field类型的,构造方法是Constructor类型的,方法是Method类型的

 

首先我们要先获取到这个字节码文件Person.class,一共有三种获取方式

第一种:使用object提供的Class<?> getClass()方法得到字节码文件,

<span style="font-size:14px;"><span style="font-size:14px;">	Person ren1=new Person();
	Class<? extends Person> claz=ren1.getClass();</span></span>

这种方式需要事先存在对象,对我们的作用并不大,我们用反射就是为了在不能创建对象时通过反射的方式实现和new对象一样的效果,所以这种方式几乎没什么作用,

接着说第二种方式:每种数据类型都有一个class属性,通过该属性得到的就是字节码文件对象

<span style="font-size:14px;"><span style="font-size:14px;">	Class<Person> claz=Person.class;</span></span>

这种方式就不需要事先存在对象了,但是这种方式需要事先存在这种数据类型

第三种方式:使用Class的静态方法forName(""),字符串由包名+类名构成

<span style="font-size:14px;"><span style="font-size:14px;">	Class<?> claz = Class.forName("cn.qianfeng.reflect.Person");</span></span>

这种方式只需要一个含有包名和类名的字符串就可以了,是常用的方式

 

接下来我们以Person类为例,其中定义了私有属性name和age,无参构造方法,带参构造方法,非静态无参方法show方法,非静态带参方法fun,静态带参方法ff

 

首先动态得到字节码文件并通过构造方法创建对象,我们先使用无参的构造方法直接使用newInstance()方法即可

<span style="font-size:14px;"><span style="font-size:14px;">		//1、得到字节码文件对象
		Class<?> claz=Class.forName("cn.qianfeng.reflect.Person");
		//2、创建对象---使用的是空参的构造方法创建对象
		Object obj=claz.newInstance();</span></span>

下面使用带参的构造方法,要先得到带参的构造方法对象然后使用newInstance方法

<span style="font-size:14px;"><span style="font-size:14px;">		//1、得到字节码文件对象
		Class<?> claz=Class.forName("cn.qianfeng.reflect.Person");
		//得到带参数的构造方法对象
		Constructor con=claz.getConstructor(String.class,int.class);</span></span>
<span style="font-size:14px;"><span style="font-size:14px;">		Object obj=con.newInstance("李四",23);</span></span>

 

创建完对象,我们就可以给对象的变量赋值了下面我们看怎样给对象的属性赋值

还是要先得到字节码文件对象
Class<?> claz = Class.forName("cn.qianfeng.reflect.Person");

然后得到属性name所属的Filed类型的对象,有两种方式

1、Field field = claz.getField("name");//的到的是public权限的属性

2、Field field = claz.getDeclaredField("name");//得到已经声明的属性包含私有属性

下面给属性赋值,name属于非静态成员变量,所以要通过对象来赋值

Object obj=claz.newInstance();

因为是私有属性,所以要先设置属性为可访问的
  field.setAccessible(true);

赋值
  field.set(obj, "张三");

 

最后我们动态获取类并调用方法

先获取字节码文件对象

Class<?> claz = Class.forName("cn.qianfeng.reflect.Person");

然后得到方法所属的Method对象,第一个参数是方法的名字,第二个参数是方法的参数类型,没有参数传递null

非静态无参的:Method method=claz.getMethod("show", null);

非静态有参的:Method m=claz.getMethod("fun", String.class);

静态有参的:Method m=claz.getMethod("ff",int.class);
执行方法时还需要对象,所以要创建对象

Object obj = claz.newInstance();

然后就可以用invoke()方法执行方法了invoke()方法传递的第一个参数是person对象,第二个参数是给方法传递的实参,没有参数传递null

非静态无参的:method.invoke(obj,null);

非静态有参的:m.invoke(obj,"haha");

静态有参的:m.invoke(null,66);//不需要对象就可以创建

 

反射就简单介绍这些,重点是把面向对象的思想建立好,反射也就不难理解了

<span style="font-size:14px;"></span> 



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值