java反射机制

反射

反射就是把java类中的各种成分映射成一个个的Java对象

例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。

 (其实:一个类中这些成员方法、构造方法、在加入类中都有一个类来描述)

反射的使用

获取class对象的三种方式

  • Class 类的实例表示正在运行的 Java 应用程序中的类和接口。也就是jvm中有N多的实例每个类都有该Class对象。(包括基本数据类型)Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的defineClass 方法自动构造的。也就是这不需要我们自己去处理创建,JVM已经帮我们创建好了。
 public static void main(String[] args) {
        //第一种方式获取Class对象  
        Student stu1 = new Student();//这一new 产生一个Student对象,一个Class对象。
        Class stuClass = stu1.getClass();//获取Class对象
        System.out.println(stuClass.getName());
        
        //第二种方式获取Class对象
        Class stuClass2 = Student.class;
        System.out.println(stuClass == stuClass2);//判断第一种方式获取的Class对象和第二种方式获取的是否是同一个
        
        //第三种方式获取Class对象
        try {
            Class stuClass3 = Class.forName("fanshe.Student");//注意此字符串必须是真实路径,就是带包名的类路径,包名.类名
            System.out.println(stuClass3 == stuClass2);//判断三种方式是否获取的是同一个Class对象
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
         //第四种获取class对象
	ClassLoader classLoader = this.getClass().getClassLoader(); // 获取当前类的类加载器
	Class clazz4 = classLoader.loadClass("com.atguigu.javase.reflect.Teacher");

      Class superclass = clazz.getSuperclass(); // 获取父类class

      Class[] interfaces = clazz.getInterfaces(); // 获取所有接口class

      Field[] declaredFields = clazz.getDeclaredFields(); // 获取所有属性

      Method[] declaredMethods = clazz.getDeclaredMethods(); // 获取所有方法对象

      Method[] methods = clazz.getMethods();//获取所有的公共方法

      getMethod可以获取本类及父类继承的公共方法	

      Method method = clazz.getDeclaredMethod("lesson", String.class, int.class); // 方法调用,方法名是必须的, 形参列表可选
      method.setAccessible(true);突破私有化

        
    }

通过反射创建对象

                  //Class clazz = Class.forName("类的全限定名称");
		try {
			// 软编码, 把编译错误转换成运行时异常!!
			Class clazz = Class.forName("com.atguigu.javase.reflect.Teacher");// 手工加载类
			Object object = clazz.newInstance(); // 通过类模板创建实体对象, 相当于new Teacher()
			System.out.println(object);
		} catch (ClassNotFoundException e) { // 类名错误, 或类没有找到
			e.printStackTrace();
		} catch (InstantiationException e) { // 找不到构造器
			e.printStackTrace();
		} catch (IllegalAccessException e) { // 非法访问时, 如果访问的目标是私有的.
			e.printStackTrace();
		} 
	}

调用构造器获取对象

      // 构造器的获取必须要给定形参类型列表
      Constructor<?> constructor = clazz.getConstructor(String.class, int.class, String.class); // 形参的数据类型列表
      // new Teacher("佟刚", 40, "男");
      Object object = constructor.newInstance("佟刚", 40, "男"); // 方法调用时给定实参, 实参必须和形参匹配

      Constructor<?> constructor2 = clazz.getConstructor(); // 获取无参构造器
      Object object2 = constructor2.newInstance();

获取类中的属性

Field nameField = clazz.getDeclaredField("name"); // 从类模板中获取声明的属性, 包括本类中的任意属性, 私有的也可以.
nameField.setAccessible(true); // 设置属性为可访问, 突破封装,私有化
nameField.set(object1, "佟刚");//等效于 object.name = "佟刚";
System.out.println(nameField.get(object1)); // System.out.println(object.name)

反射获取在类上的注解

@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnn {
	String value() default "缺省值";
}

@MyAnn("张三")
class Teacher implements Serializable

Class clazz = Class.forName("com.atguigu.javase.reflect.Teacher");
MyAnn annotation = (MyAnn)clazz.getAnnotation(MyAnn.class); // 获取类上使用的注解
System.out.println(annotation);
String value = annotation.value();

posted @ 2020-05-07 14:10  silence022  阅读(46)  评论(0)    收藏  举报