美文网首页
java的反射机制

java的反射机制

作者: Veteor | 来源:发表于2016-10-05 20:26 被阅读0次
    什么是反射?

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

    通过反射来了解类

    1、类由属性,方法,构造函数等组成
    2、给定一个类或对象,通过反射机制可以动态的了解类的属性方法,构造函数,创建对象,调用方法,改写属性
    3、应用场景:(1)运行时,动态的情况下应对外面传入的“类名”,对象实例等。(2)只知道类名字符串。(3)通常应用到框架中 。

    常用的反射操作 (以Dog这个类为例子)
    package learnReflect;
    
    public class Dog {
        public String name;
        public int age;
        private String owner;
        public  Dog(){
            
        }
        public Dog(String name,int age){
            this.name = name;
            this.age = age;
        }
        public void bark(){
            System.out.println("汪汪");
        }
        public void celebrateBirthday(){
            System.out.println(name+"生日快乐");
            addAge();
        }
        private void addAge(){
            age = age+1;
        }
    }
    

    1、通过一个对象获得完整的包名和类名

    public static void getClassFullName(Dog d){
            System.out.println("1.获取包名和类名");
            Class c = d.getClass();
            System.out.println("类名: "+c.getName());
            System.out.println("包名: "+c.getPackage().getName());
        }
    

    2、获得Class对象 3种方法

    public static void getClassInstance(){
            System.out.println("2.获得类实例 - 2种方法");
            try {
                String className = "learnReflect.Dog";
                Class c = Class.forName(className);
                System.out.println("method 1:"+c.getName());
                
                Class d = Dog.class;
                System.out.println("method 2:"+c.getName());
                
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    

    3、了解类的各种信息

    1、获取本类的声明方法,调用类的方法。

    public static void getClassMethod(){
    Class<Dog> dogClazz = Dog.class;
    Method[] methods = dogClazz.getMethods();//能获取Dog类所有的public方法,不能获取private
    Method[] methods2 = dogClazz.getDeclaredMethods();//只能获取Dog类自己定义的所有方法包括私有方法
    for(Method m : methods)
    System.out.println(m.getName());
    try {
    //"bark"是方法名,不存在时会抛出异常,new Class[]{}是参数类型数组,无参数就为空
    Method method = dogClazz.getMethod("bark", new Class[]{});
    //invoke方法用于调用方法,参数为类的实例和方法的参数
    method.invoke(dogClazz.newInstance());
    } catch (Exception e) {
    e.printStackTrace();
    }
    }

    >2、获得父类信息
    >```
    public static void getClassSuperClassInfo(){
            Class<Dog> dogClazz = Dog.class;
            System.out.println("Dog父类的名字是:"+dogClazz.getSuperclass());
        }
    

    3、获得接口信息

    public static void getClassInterfaceInfo(){
    Class<Dog> dogClazz = Dog.class;
    for(int i = 0; i< dogClazz.getInterfaces().length;i++)
    System.out.println(dogClazz.getInterfaces()[i].getName());
    }

        
    4、根据Class对象创建instance实例 
    

    public static void getInstance(){
    System.out.println("创建对象实例======");
    Class<Dog> dogClazz = Dog.class;
    try {//方法1:无参的构造方法
    Object o = dogClazz.newInstance();
    System.out.println("创建的对象是:"+o);
    //方法2:有参数的构造方法
    Constructor c = dogClazz.getConstructor(new Class[]{String.class,int.class});
    Dog o2 = (Dog) c.newInstance("大黄",4);
    System.out.println("创建的对象是:"+o2.name);
    } catch (InstantiationException e) {
    e.printStackTrace();
    } catch (IllegalAccessException e) {
    e.printStackTrace();
    } catch (NoSuchMethodException e) {
    e.printStackTrace();
    } catch (SecurityException e) {
    e.printStackTrace();
    } catch (IllegalArgumentException e) {
    e.printStackTrace();
    } catch (InvocationTargetException e) {
    e.printStackTrace();
    }
    }

    5、操作成员变量
    

    public static void changeFiled(){
    System.out.println("改变成员变量======");
    Class<Dog> dogClazz = Dog.class;
    try {
    Object o = dogClazz.newInstance();
    //方法2
    Constructor c = dogClazz.getConstructor(new Class[]{String.class,int.class});
    Dog o2 = (Dog) c.newInstance("大黄",4);
    Field[] fields = dogClazz.getFields();
    for(Field f : fields){
    System.out.println(f.getName());
    }
    Field[] fields2 = dogClazz.getDeclaredFields();
    for(Field f : fields2){
    System.out.println(f.getName());
    }
    Field f = dogClazz.getField("name");
    f.set(o2, "大黑");
    System.out.println(f.get(o2));
    // getDeclaredField()用于获取私有成员变量,必须设置setAccessible(true)才能改变
    Field f2 = dogClazz.getDeclaredField("owner");
    f2.setAccessible(true);
    f2.set(o2, "张三");
    System.out.println(f2.get(o2));
    } catch (InstantiationException e) {
    e.printStackTrace();
    } catch (IllegalAccessException e) {
    e.printStackTrace();
    } catch (NoSuchMethodException e) {
    e.printStackTrace();
    } catch (SecurityException e) {
    e.printStackTrace();
    } catch (IllegalArgumentException e) {
    e.printStackTrace();
    } catch (InvocationTargetException e) {
    e.printStackTrace();
    } catch (NoSuchFieldException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }

    相关文章

      网友评论

          本文标题:java的反射机制

          本文链接:https://www.haomeiwen.com/subject/jyteyttx.html