java的反射机制

在我们写代码时,若我们使用未定义或引入的类,编译器就会报错,无法生成class文件,java反射机制可以解决这个问题!


我对反射机制的理解就是在运行期动态加载所需要的类,运行我们想要调用的方法,访问类的成员域,创建一个类的对象。在编译期编译器不会去纠结这个类到底存不存在,只有到运行期才知道这个类、方法等是否存在,举个例子,在合作开发时,我们可能需要用到其他程序媛写的类,但其他程序媛不一定写好这个类,那我们要等到她们写好后在开始写?效率不高,java反射机制允许我们在自己的代码中引用程序媛未写好的类,同时通过编译。(这是强迫症的福音啊,不然写代码一堆红线,难受........),可以用下面的代码感受下:

package pkgtry;
public class Try {
    public static void main(String[] args) {
        try
        {
            Class x=ClassLoader.getSystemClassLoader().loadClass("pkgtry.woyongyuanxihuanjisuanji");
        }
        catch(ClassNotFoundException e)
        {
            System.out.println("未找到类");
        }
    } 
}

编译是可以通过的。


如何在我们的代码中动态加载类呢?可以利用java.lang.Class的静态成员方法forName(String classname)throws ClassNotFoundException代码如下

package pkgtry;
class A
{
  static 
  {
      System.out.println("加载类A");
  }
}
public class Try {
    public static void main(String[] args) {
        try
        {
            Class.forName("pkgtry.A");//参数为类的全限定名,即包名+类名
        }
        catch(ClassNotFoundException e)
        {
            System.out.println("未找到类");
        }
    } 
}
运行结果为

也可以调用ClassLoader类的loadClass方法,关于两者的区别可以看我的另一篇博客:点击打开链接

说到类加载,这里啰嗦一下,每个实例对象均含有指向方法区中类信息的指针,这个指针可以通过getClass获得,如果我们知道类名,可以通过类名.class获得该指针,通过该指针,我们可以猥琐欲为,另外令我诧异的是基本数据类型也拥有该指针,如下所示:

package pkgtry;
public class Try {
    public static void main(String[] args) {
            Class x=int.class;
    } 
}
JVM会为每个基本数据类型(包括void)创建一个类对象,该类对象很奇葩,是final abstract public修饰的,没有方法,没有成员域,之所以这么做可能是为了符合“一切都是对象”的设计理念,利用getMethod获取类的方法时,第二个参数必须是类对象,若我们想调用的函数中的形参有基本数据类型,就可以用上基本数据类型的类对象。


这里说一下常用的反射机制的函数,有些包需要自己导入,这里就不一一列举了,毕竟可以用工具自带的修复导入,这些函数都是通过forName返回的Class对象调用的。


类修饰符:    

     int getModifiers(),获取类修饰符,该方法返回一个整形,具体判断可以用 java.lang.reflect.Modifier的一系列方法:

Modifier.isAbstract(int modifiers);
Modifier.isFinal(int modifiers);
Modifier.isInterface(int modifiers);
Modifier.isNative(int modifiers);
Modifier.isPrivate(int modifiers);
Modifier.isProtected(int modifiers);
Modifier.isPublic(int modifiers);
Modifier.isStatic(int modifiers);
Modifier.isStrict(int modifiers);
Modifier.isSynchronized(int modifiers);
Modifier.isTransient(int modifiers);
Modifier.isVolatile(int modifiers);
返回布尔值。使用实例如下:

import java.lang.reflect.Modifier;
public class Try {
    public static void main(String[] args) {
            Class x=int.class;
            int modifiers=x.getModifiers();
            System.out.println(Modifier.isPublic(modifiers));
            System.out.println(Modifier.isAbstract(modifiers));
            System.out.println(Modifier.isFinal(modifiers));
            System.out.println(Modifier.isInterface(modifiers));
            System.out.println(Modifier.isNative(modifiers));
            System.out.println(Modifier.isPrivate(modifiers));
            System.out.println(Modifier.isProtected(modifiers));
            System.out.println(Modifier.isStatic(modifiers));
            System.out.println(Modifier.isStrict(modifiers));
            System.out.println(Modifier.isSynchronized(modifiers));
            System.out.println(Modifier.isTransient(modifiers));
            System.out.println(Modifier.isVolatile(modifiers));
    } 
}
输出为:

说明int的类对象是public final abstract修饰的。


类名:

     String getName():返回类的全限定名。

     String getSimpleName():仅返回类名。

     String getSuperclass():返回直接父类的全限定名。


包:

Package getPackage():获取包信息。这个类的相关操作之后会补上一篇博客。


接口:

Class[] getInterface():获取当前类(不包含父类)实现的接口。


方法:

     Method[] getMethods():获取方法构成数组,这些方法都是public修饰的,包括继承的。

     Method getMethod(String functionname,Class .......)throws NoSuchMethodException:返回对应方法的Method对象。该方法必须是public修饰的,若该方法不存在形参,则第二个参数为null,否则传入形参的类对象,当方法不存在时,抛出NoSuchMethodException异常。

     Method getDeclaredMethod(String name, Class[] parameterTypes):返回对应的非公有方法,参数与上述一致。

     Method[] getDeclaredMethods() :返回对应的非公有方法组成的数组。

     Method类型常用方法:

    Class getReturnType():返回方法返回类型的类对象。

    Class[] getParameterTypes():返回方法形参的类对象。

    Object invoke(Object Myobject,Object ......)throws IllegalAccessException,InvocationTargetException调用方法,第一个参数为实例对象的this指针,若方法为静态方法,可以填为null,第二个参数为方法的形参,当返回值是非共有时,会抛出IllegalAccessException异常,当调用的方法抛出异常时,invoke会抛出InvocationTargetException异常。


构造器:

      Constructor[] getConstructors():返回public修饰的构造器组成的数组。

      Constructor getConstructor(Class ......)throws NoSuchMethodException:返回含有对应形参的public修饰的构造器。

      Constructor常用方法如下:

      Class[]  getparameterType():返回构造函数的形参的类对象数组。

  Object newInstance(Object .......)throws NoSuchMethodException,InstantiationException,IllegalAccessException,InvocationTargetException,创建实例对象,形参与实参必须一一对应。当创建抽象类或接口的实例对象时,会抛出InstantiationException异常。


变量:


        Field[] getFields()throws SecurityException:返回共有成员域构成的数组。SecurityException异常以后研究

        Field getFiled(String name)throws NoSuchFieldException,SecurityException:返回名为name的共有成员域。若不存在对应名字的成员域,则抛出NoSuchFieldException异常。

        Field getDeclaredField(String name):返回名为name的非公有成员域。

         Field[] getDeclaredFields():返回非公有成员域构成的成员域数组。  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值