• 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");
        }
    }
  • 相关阅读:
    优先队列用法详解
    chenzl
    2020面向对象程序设计寒假作业1
    1.自我介绍

    洛谷U32670 小凯的数字(比赛)
    洛谷1417 烹调方案
    高等软工课程总结
    西电B楼导航
    毕业前夕随想
  • 原文地址:https://www.cnblogs.com/1012hq/p/11310683.html
Copyright © 2020-2023  润新知