简单说说java中的反射

 反射就是把Java类中的各个组成部分进行解剖,并映射成一个个的Java对象,拿到这些对象后可以做一些事情。

既然说反射是解剖Java类中的各个组成部分,所以说咱们得知道一个类中有哪些部分?

一个类里一般有构造函数、方法、成员变量(字段/属性)这三部分组成

Class类

实际上,我们创建的每一个类也都是对象,即类本身是java.lang.Class类的实例对象。

这个实例对象称之为类对象,也就是Class对象。

Class类本身没有构造方法,得到Class类实例的3种方式 **(1)、Class.forName("包名.类名"); **最常用,可写在配置文件里

(2)、对象.getClass();

(3)、类名.class;

把解剖出来的部分,分别用Constructor(构造)、Method(方法)、Field(属性)对象表示,而这3个类都是AccessibleObject的子类。注意:这3个类默认都只能访问public的,要想访问其他的要设置访问权限

forName("包名.类名");实例化class对象
getConstructors()得到一个类中的全部构造方法
getDeclaredFields()得到一个类的父类的全部属性
getFields()得到一个类中的全部属性
getMethods()得到一个类中的全部方法
getMethod(String 方法名,该方法的各个参数的Class对象)得到一个指定的方法
getInterfaces()得到一个类实现的全部接口
getName()得到一个类完整的“包名.类名”的名称
getPackage()得到一个类的包,返回类型是 Package
getSuperclass得到一个类的父类
newInstance()根据Class定义的类实例化对象
isArray()判断此 Class是否为一个数组

注意:newInstance()只能实例化具有无参构造方法的类

注意:getConstructor()只能反射public的构造函数

 getDeclaredConstructor()可以读取任何权限的构造函数,

如果是私有的构造方法就要设置一下暴力反射才可以 setAccessible(true);//暴力反射

Constructor构造对象

getModifiers()得到构造方法的修饰符
getName()得到构造方法的名称
getParameterTypes()得到构造方法中参数的信息
toString()返回构造方法的信息
newInstance(该构造方法的各种参数)返回实例
class shit{
    int age;
    String str;
    public shit(int age,String str)
    {
        this.age=age;
        this.str=str;
    }
    public String toString()
    {
        return str+age;
    }
}
public class test {
    public static void main(String[] args) throws Exception {
        Class c=shit.class;
        Constructor[] con=c.getConstructors();
        shit s=(shit) con[0].newInstance(123,"ui");
        System.out.print(s);
    }
}

这是用有多个参数的构造方法来实例化对象的 例子

Method

getModifiers()得到方法的修饰符
getName()得到方法的名称
getParameterTypes()得到方法中参数的信息
getReturnTypes()得到返回类型
toString()返回方法的信息
getExceptionTypes()返回该方法可能抛出的异常
invoke(该类的对象,该方法的参数.......)调用该方法

Field

get(Object)得到一个对象中属性的具体内容
set(Object指定对象,Object 值)设置指定对象中属性 的内容
getModifiers()得到属性的修饰符
getName()返回该属性的名称
isAccessible()判断是否可以被访问
setAccessible(boolean 是/否)设置是否可被访问
setAccessible(AccessibleObject[],boolean)设置一组属性是否可被外部访问
toString()返回此Field的信息

Array

通过反射操作数组,一下都是静态方法

get(数组,int index)返会指定位置的元素
getLength()返回数组长度
set(数组,int index,值)设置指定位置的值
newInstance(数组的Class对象,int 长度)根据已有的数组类型开辟一个新的数组对象

得到数组Class对象的 方法

数组对象.getClass().getComponentType()

ClassLoader类加载器

以下是系统的3个类加载器,加载顺序依次降低

Bootstrap CLassloder不是类,由c++编写
Extention ClassLoader(ExtClassLoader)真实的类
AppClassLoader真实的类

每一个类都有父加载器,除了Bootstrap CLassloder,这是父加载器示意图

注意的是父加载器 不是 父类,这是各个加载器的继承关系,Bootstrap CLassloder不是java中的类,它本身是java虚拟机的一部分(int.class与String.class就是她加载的)

 

双亲委托

一个类加载器查找class和resource时,是通过“委托模式”进行的。

它首先判断这个class是不是已经加载成功,如果当前的类加载器没有查询到这个class对

象已经加载就请求父加载器进行操作,然后以此类推。直到Bootstrap ClassLoader。

如果Bootstrap ClassLoader也没有加载过此class实例,那么它就会从它指定的路径中去查找,如果查找成功则返回**,如果没有查找成功则交给子类加载器去查找。以此类推,总的来说是一个递推的过程

这种机制就叫做双亲委托。整个流程可以如下图所示:

 

系统类库使用系统的类加载器,非系统的类才能使用自定义的加载器

自定义ClassLoader

  1. 编写一个类继承自ClassLoader抽象类。
  2. 复写它的findClass()方法。
  3. 在findClass()方法中调用defineClass()。

defineClass(),它能将class二进制内容转换成Class对象,

defineClass(类名,byte数组,int 起始,int 结束) 传入一个装有class文件内容的字节数组转换为Class对象

Class的getClassLoader()方法得到类加载器

Classloder的loadClass(String path)方法传入地址返回Class对象


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值