Java反射

一、什么是反射

反射的概念是由smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在lisp和面向对象方面取得了成绩。其中lead/lead++
、openc++ 、metaxa和openjava等就是基于反射机制的语言。最近,反射机制也被应用到了视窗系统、操作系统和文件系统中。

反射本身并不是一个新概念,尽管计算机科学赋予了反射概念新的含义。在计算机科学领域,反射是指一类应用,它们能够自描述和自控制。也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-representation)和监测(examination),并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。

在这里插入图片描述

二、反射的机制有什么作用

通过反射可以使程序代码访问装载到JVM中的类的内部信息。
(1)获取已装载类的成员变量信息.
(2)获取已装载类的方法.
(3)获取已装载类的构造方法信息.
通过”获取已装载类的成员变量信息”功能可以获取JVM中的Class对象,获取了对象之后可以实现很多功能,比方说IOC容器通过反射创建对象、或者是动态代理。

三、反射机制相关的重要的类

含义
java.lang.Class代表整个字节码。代表一个类型,代表整个类。
java.lang.reflect.Method代表字节码中的方法字节码。代表类中的方法。
java.lang.reflect.Constructor代表字节码中的构造方法字节码。代表类中的构造方法。
java.lang.reflect.Field代表字节码中的属性字节码。代表类中的成员变量(静态变量+实例变量)。

注:必须先获得Class才能获取Method、Constructor、Field

四、获取Class的方式

如果要操作一个类的字节码,需要首先获取到这个类的字节码,怎么获取java.lang.Class
(1)Class.forName(“完整类名带包名”) 静态方法
(2)对象.getClass()
(3)任何类型.class
以上三个的返回值都是Class类型

4.1Class 类的常用方法
方法名功能
static Class forName(String name)返回指定类名name 的class对象
Object newInstance()调用缺省构造函数,返回该class对象的一个实例
getName()返回次class对象所表示的实体(类、接口、数组、基本类型等)
Class [] getInterfaces()获取当前class对象的接口
ClassLoader getClassLoader()返回该类的类加载器
Class getSuperclass()返回表示Class所表示的实体的超类的Class
Constructor[] getConstructor()返回一个包含某些Constructor对象的数组
Field[] getDeclaredFields()返回Field对象的一个数组
Method getMethod(String name.Class…paramTypes)返回一个Method对象,此对象的形参类型为paramType
五、反射的API

Class 类:代表一个类或接口,在反射中用于获取类的相关信息。可以使用 Class.forName(“className”) 来获取类的 Class 对象。

Constructor 类:代表类的构造函数,可以使用 Class.getConstructors() 获取所有公共构造函数,或者使用 Class.getDeclaredConstructor(parameterTypes) 获取指定参数类型的构造函数。

Field 类:代表类的字段,可以使用 Class.getFields() 获取所有公共字段,或者使用 Class.getDeclaredField(fieldName) 获取指定字段。

Method 类:代表类的方法,可以使用 Class.getMethods() 获取所有公共方法,或者使用 Class.getDeclaredMethod(methodName, parameterTypes) 获取指定方法。

5.1常用的方法
//获取包名、类名
clas.getPackage().getName()//包名
clas.getSimpleName()//类名
clas.getName()//完整类名
 
//获取成员变量定义信息
getFields()//获取所有公开的成员变量,包括继承变量
getDeclaredFields()//获取本类定义的成员变量,包括私有,但不包括继承的变量
getField(变量名)
getDeclaredField(变量名)
 
//获取构造方法定义信息
getConstructor(参数类型列表)//获取公开的构造方法
getConstructors()//获取所有的公开的构造方法
getDeclaredConstructors()//获取所有的构造方法,包括私有
getDeclaredConstructor(int.class,String.class)
 
//获取方法定义信息
getMethods()//获取所有可见的方法,包括继承的方法
getMethod(方法名,参数类型列表)
getDeclaredMethods()//获取本类定义的的方法,包括私有,不包括继承的方法
getDeclaredMethod(方法名,int.class,String.class)
 
//反射新建实例
clazz.newInstance();//执行无参构造创建对象
clazz.newInstance(222,"韦小宝");//执行有参构造创建对象
clazz.getConstructor(int.class,String.class)//获取构造方法
 
//反射调用成员变量
clazz.getDeclaredField(变量名);//获取变量
clazz.setAccessible(true);//使私有成员允许访问
f.set(实例,);//为指定实例的变量赋值,静态变量,第一参数给null
f.get(实例);//访问指定实例变量的值,静态变量,第一参数给null

//反射调用成员方法
Method m = Clazz.getDeclaredMethod(方法名,参数类型列表);
m.setAccessible(true);//使私有方法允许被调用
m.invoke(实例,参数数据);//让指定实例来执行该方法
六、反射创建对象的两个步骤

1.先获取到这个有参数的构造方法【用ClassgetDeclaredConstructor()方法获取】
2.调用构造方法new对象【用Constructor类的newInstance()方法new对象】
通过反射调用构造方法实例化java对象,如下:

class Test{
public static void main(String[] args) throws Exception {
        //不适用反射创建对象
        Preson p1 = new Preson();
        Preson p2 = new Preson(123, "zhangsan", "2001-10-19", false);

        //使用反射机制创建对象(以前)
        Class vipClass = Class.forName("javase.reflectBean.Vip");
        // 调用无参数构造方法
        Object obj1 = PresonClass.newInstance();//Class类newInstance方法
        System.out.println(obj1);

        //使用反射机制创建对象(现在)
        // 调用有参数的构造方法怎么办?
        // 第一步:先获取到这个有参数的构造方法
        Constructor c1= PresonClass.getDeclaredConstructor(int.class, String.class, String.class, boolean.class);
        // 第二步:调用构造方法new对象
        Object obj2 = c1.newInstance(321, "lsi", "1999-10-11", true);//Constructor类的newInstance方法
        System.out.println(obj2);

        // 获取无参数构造方法
        Constructor c2 =  PresonClass.getDeclaredConstructor();
        Object obj3 = c2.newInstance();
        System.out.println(obj3);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值