java的反射机制及意义

反射的意义
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。(说的直白点就是为了代码简洁,提高代码的复用率,外部调用方便,源代码,反编译都能看到。)

package avicit.mms.common;

interface Animal { //动物接口
    public void say() ; //叫声
}

class Dog implements Animal{ //定义狗
    public void say() {
        System.out.println("汪、汪、汪!!!"); 
    } 
}

class Cat implements Animal{
    public void say() {
        System.out.println("喵、喵、喵!!!"); 
    }
}

class Factory{
    public static Animal getInstance(String className){
        Animal animal = null ;
        try{
            animal = (Animal) Class.forName(className).newInstance() ;
        }catch(Exception e ){
            e.printStackTrace() ;
        }
        return animal ;
    }
}

public class Test{
    public static void main(String args[]){
        //通过工厂类取得接口实例,传入完整的包.类名称
        Animal animal = Factory.getInstance("avicit.mms.common.Dog") ;
        if(animal!=null){ //判断是否取得接口实例
            animal.say() ;
        }
    }
}

输出:
汪、汪、汪!!!

  如果不用反射,那么我们如果再加一个老虎类,就得在Factory里判断,每添加一个类都要修改一次Factory,但用了反射只用在调用的时候传入完整的类名就可完成。结果:用反射,修改一处代码;不用反射,修改两处代码。

反射一般用于:

  1. JDBC中,利用反射动态加载了数据库驱动程序。
  2. Web服务器中利用反射调用了Sevlet的服务方法。
  3. Eclispe等开发工具利用反射动态刨析对象的类型与结构,动态提示对象的属性和方法。
  4. 很多框架都用到反射机制,注入属性,调用方法,如Spring。

反射机制的优缺点:

  1. 优点:可以动态执行,在运行期间根据业务功能动态执行方法、访问属性,最大限度发挥了java的灵活性。
  2. 缺点:对性能有影响,这类操作总是慢于直接执行java代码。

反射机制的作用:

  1. 在运行时判断任意一个对象所属的类
  2. 在运行时构造任意一个类的对象
  3. 在运行时判断任意一个类所具有的成员变量和方法
  4. 在运行时调用任意一个对象的方法

反射的使用:

  1. 通过一个全限类名创建一个对象
    1. Class.forName(“全限类名”); 例如:com.mysql.jdbc.Driver Driver类已经被加载到 jvm中,并且完成了类的初始化工作就行了
    2. 类名.class; 获取Class<?> clz 对象
    3. 对象.getClass();
  2. 获取构造器对象,通过构造器new出一个对象
    1. Clazz.getConstructor([String.class]);
    2. Con.newInstance([参数]);
  3. 通过class对象创建一个实例对象(就相当与new类名()无参构造器)
    1. Cls.newInstance();
  4. 通过class对象获得一个属性对象
    1. Field c=cls.getFields():获得某个类的所有的公共(public)的字段,包括父类中的字段。
    2. Field c=cls.getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的声明字段
  5. 通过class对象获得一个方法对象
    1. Cls.getMethod(“方法名”,class……parameaType);(只能获取公共的)
    2. Cls.getDeclareMethod(“方法名”);(获取任意修饰的方法,不能执行私有)
    3. M.setAccessible(true);(让私有的方法可以执行)
  6. 让方法执行
    1. Method.invoke(obj实例对象,obj可变参数);-----(是有返回值的)
package avicit.mms.common;

import java.lang.reflect.*;

public class Main {
    public static void main(String[] args) throws Exception{
        //返回A的构造方法
        Constructor c = A.class.getConstructor();
        //返回A类的所有为public 声明的构造方法
        Constructor[] cons = A.class.getConstructors();
        //返回A类所有的构造方法,包括private
        Constructor[] cons2 = A.class.getDeclaredConstructors();
        //返回A类的第一个public 方法
        Method m = A.class.getMethod("say");
        //执行
        m.invoke(A.class.newInstance(), null);
        //返回A类所有的public 方法
        Method[] ms = A.class.getMethods();
        //返回A类所有的方法,包括private
        Method[] allMs = A.class.getDeclaredMethods();
        //返回A类的public字段
        Field field = A.class.getField("i");
        System.out.println(field.get(A.class.newInstance()));
        //返回A类的static 字段
        System.out.println(field.get(null));
    }
}

class A{
    public int i = 1;
    public static int b = 2;
    public A(){
        System.out.println("无参构造");
    }
    private A(String s){
        System.out.println("有参构造"+s);
    }
    
    public void say(){
        System.out.println("say");
    }
}
原文地址:https://www.cnblogs.com/1012hq/p/11310683.html