反射机制

反射

反射是什么

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

反射的用途

在开发的过程中,有时会遇到某个类的某个成员变量、方法或是属性是私有的。这时候就可以利用Java的反射机制通过反射来获取所需的私有成员或是方法。

反射常用类

我们对Java反射机制的学习,设计上基本就等同于对Class类的用法的学习。所以,要了解相关的类及其用法。

1. Class

Class类是java反射机制的核心,我们可以提供Class类动态的加载某个类。

Class c =Class.forName("Reflect.ReflectClass");

Class类获取对象的方式有3种。

  1. 运用getClass();
  2. .运用class语法;
  3. 运用Class.forName()语法(常用)
Class c1=new ReflectClass().getClass();
Class c2=ReflectClass.class;
Class c3 =Class.forName("Reflect.ReflectClass");

2. Constructor

Constructor类的对象代表"构造器",Constructor类对象我们要通过Class类对象调用方法来获取。

源码:public Constructor getConstructor(Class<?>... parameterTypes)

Constructor[] constructor=class1.getDeclaredConstructors();//获取所有构造器
Constructor constructor1=class1.getDeclaredConstructor(null);//获取无参构造器
Constructor constructor2=class1.getConstructor(int.class,String.class);//获取相应参数的构造器
//调用构造器
ReflectClass reflectClass1=(ReflectClass) constructor1.newInstance();//调用无参构造器
ReflectClass reflectClass2=(ReflectClass) constructor2.newInstance(18,"小杨");//调用有参构造器

3. Field

Field类的对象代表”属性“,Field类对象的获取要通过Class类对象调用方法来获取。

源码: public Field getDeclaredField(String name)

Field[] field=class1.getDeclaredFields();//获取所有属性的Field对象
Field field1=class1.getDeclaredField("name");//获取name属性的Field对象
//设置属性值
field1.setAccessible(true);//跳过安全检查,可以直接访问私有属性和方法
field1.set(reflectClass1,"小杨");//参数左边是对象,右边是属性值

4. Method

Method类的对象代表”方法“,Method类对象的获取要通过Class类对象调用方法来获取。

通过指定的方法名参数获取到Method类方法对象

源码: public Method getDeclaredMethod(String name, Class<?>... parameterTypes)

Method[] methods=class1.getDeclaredMethods();//获得所有方法
Method method=class1.getDeclaredMethod("setName",String.class);//获得指定名字的方法,
Method method1=class1.getDeclaredMethod("sayName",null);//获取无参方法
//调用方法
method.invoke(reflectClass1,"小杨");//参数左边是对象,右边是方法所需的参数
method1.invoke(null);//调用无参方法

反射弊端

反射机制的缺点是会大大降低程序的执行效率。

public class TestReflect {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
        Class class1=TestReflect.class;
        long reflectStart1=System.currentTimeMillis();
        TestReflect testReflect=(TestReflect) class1.newInstance();
        Method method1=class1.getDeclaredMethod("fun",null);
        for (int i = 0; i < 10000; i++) {
            method1.invoke(testReflect,null);
        }
        long reflectEnd1=System.currentTimeMillis();

        long reflectStart2=System.currentTimeMillis();
        TestReflect testReflect2=new TestReflect();
        for (int i = 0; i < 10000; i++) {
            testReflect2.fun();
        }
        long reflectEnd2=System.currentTimeMillis();

        System.out.println("反射执行时间:"+(reflectEnd1-reflectStart1));
        System.out.println("普通执行时间:"+(reflectEnd2-reflectStart2));
    }
    public void fun(){}
}

运行结果:

反射机制

上一篇:c# using(){}


下一篇:记录一次泛型的使用