反射

515 阅读3分钟

1:反射概述

反射是java语言的一个特性,它允程序在运行时来进行自我检查并且对内部的成员进行操作。 反射是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,对于任意一个对象,都能够调用它的任意方法和属性,这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

总而言之,放射允许一个java的类获取他所有的成员变量和方法并且显示出来。

2:为什么要用反射?

Java Reflection功能非常强大,并且非常有用,比如:

  • 获取任意类的名称、package信息、所有属性、方法、注解、类型、类加载器等
  • 获取任意对象的属性,并且能改变对象的属性
  • 调用任意对象的方法
  • 判断任意一个对象所属的类
  • 实例化任意一个类的对象
  • 通过反射我们可以实现动态装配,降低代码的耦合度,动态代理等。

3: 获取class文件对象的三种方法

public class demo {
    public static void main(String[] args) {
//使用类的class属性来获取该类对应的class对象
        Class<student> c1 = student.class;
        System.out.println(c1);

        Class<student> c2 = student.class;
        System.out.println(c2==c1);
        System.out.println("----------");

//        调用对象的getclass方法,返回该对象所属类对应的class对象
        student s=new student();
        Class<?extends student>c3=s.getClass();
        System.out.println(c1==c3);
        System.out.println("--------");

//使用clas中的静态方法forname(Sting classname)
        try {
            Class<?> C4=Class.forName(" 假期一.反射.获取class类的对象.student");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            System.out.println();
        }
    }

}

4:反射实例

1:反射获取成员变量并使用

public class demo1 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//       得到class对象
        Class<?> C = Class.forName("假期一.反射.反射获取构造方法并使用.练习.t1");
        Field[] files = C.getDeclaredFields();
        for (Field filed : files
        ) {
            System.out.println(filed);
        }
        System.out.println("------------");
// 返回一个filed对象,该对象反应由该Class对象表示的类或接口的指定声明字段
        Field addr = C.getField("address");
//        student s = new student();
//        s.adress = "西安";
//        获取无参构造方法创造对象
        Constructor<?> con = C.getConstructor();
        Object obj = con.newInstance();
        addr.set(obj, "西安");
//    给obj的成员变量的address赋值为西安
        System.out.println(obj);
        }
        }

2:反射获取成员方法并使用

public class demo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//        获取class对象
        Class<?> C = Class.forName("假期一.反射.反射获取构造方法并使用.练习.t1");

        Method[] methods = C.getMethods();
        for (Method method : methods
        ) {
            System.out.println(method);
        }
        System.out.println("-----------");


        Method m = C.getMethod("method1");
//获取无参构造方法创建对象
        Constructor<?> con = C.getConstructor();
        Object obj = con.newInstance();
//        用于调用成员方法的方法
        m.invoke(obj);
//
    }
}

3:反射获取构造方法并使用

public class demo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {

//      获取Class对象
        Class<?> c = Class.forName("src.假期一.反射.反射获取构造方法并使用");
//        Constructor<?>[] cons = c.getConstructors();
//        Constructor<?> []cons = c.getDeclaredConstructor();

//        for (Constructor con : cons) {System.out.println(con);}
//        参数:你要获取的构造方法的参数的个数和数据类型对应的字节码对象
        Constructor<?> con = c.getConstructor();
//construct提高了一个类的单个构造函数的信息和访问权限
        Object obj=con.newInstance();
        System.out.println(obj);

    }
}

5:反射获取类加载器

public class classloaderdemo {
    public static void main(String[] args) {
//        返回用于委托的系统类加载器
        ClassLoader c = ClassLoader.getSystemClassLoader();
        System.out.println(c);

//ClassLodaer getparent();返回父类加载器进行委托
        ClassLoader c2 = c.getParent();
        System.out.println(c2);

        ClassLoader c3 = c2.getParent();
        System.out.println(c3
        );
    }
}