Java 反射机制学习笔记

概念

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。
反射是Java中一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以再运行时装配,无需在组件之间进行源代码链接。但是反射使用不当会成本很高!

作用

  1. 反编译:.class–>.java。
  2. 通过反射机制访问java对象的属性,方法,构造方法等。

功能实现

1.获取类

         //第一种方式,通过包名.类名获取,需要try-catch异常
        Class demoClass1 = null;
        try {
           demoClass1 = Class.forName("JavaDemo.Demo");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        //第二种方式:java中每个类型都有class属性
        Class demoClass2 = Demo.class;
        //第三种方式:java语言中任何一个java对象都有getClass方法
        Demo demo = new Demo();
        Class demoClass3 = demo.getClass();

2.创建对象

         //创建此Class 对象所表示的类的一个新实例
        //调用了Employee的无参数构造方法.
        Object object = null;
        try {
            object = demoClass1.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }

3.获取属性

1. 所有的属性
 //获取类中属性数组
        Field[] fs = demoClass1.getDeclaredFields();
        StringBuilder sb = new StringBuilder();
        sb.append(Modifier.toString(demoClass1.getModifiers()) + " class " + demoClass1.getSimpleName() + "{\n");//里边的每一个属性
        for (Field field : fs) {
            sb.append("\t");//空格
            sb.append(Modifier.toString(field.getModifiers()) + " ");//获得属性的修饰符,例如public,static等等
            sb.append(field.getType().getSimpleName() + " ");//属性的类型的名字
            sb.append(field.getName() + ";\n");//属性的名字+回车
        }
        sb.append("}");

        System.out.println(sb);
2.指定的属性
        //获取id的属性
        Field idF = null;
        try {
            idF = demoClass1.getDeclaredField("id");
            //打破封装
            idF.setAccessible(true); //使用反射机制可以打破封装性,导致了java对象的属性不安全。
            //给o对象的id属性赋值"110"
            idF.set(object, 110); //set
            System.out.println(idF.get(object));//get
        } catch (Exception e) {
            e.printStackTrace();
        }

获取方法和接口

与获取属性大同小异,给出方法表格,不再写代码。

方法关键字 含义
getDeclaredMethods() 获取所有的方法
getReturnType() 获得方法的放回类型
getParameterTypes() 获得方法的传入参数类型
getDeclaredMethod(“方法名”,参数类型.class,……) 获得特定的方法
构造方法关键字 含义
getDeclaredConstructors() 获取所有的构造方法
getDeclaredConstructor(参数类型.class,……) 获取特定的构造方法
父类和父接口 含义
getSuperclass() 获取某类的父类
getInterfaces() 获取某类实现的接口

示例代码

1.Demo.class

public class Demo {
    private int id;
    public String name;

    public static void hello() {
        System.out.println("hello world!");
    }
}

2.Reflex.class

public class Reflex {
    public static void main(String[] args) {
        //第一种方式,通过包名.类名获取,需要try-catch异常
        Class demoClass1 = null;
        try {
            demoClass1 = Class.forName("JavaDemo.Demo");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        //第二种方式:java中每个类型都有class属性
        Class demoClass2 = Demo.class;
        //第三种方式:java语言中任何一个java对象都有getClass方法
        Demo demo = new Demo();
        Class demoClass3 = demo.getClass();

        //创建此Class 对象所表示的类的一个新实例
        //调用了Employee的无参数构造方法.
        Object object = null;
        try {
            object = demoClass1.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        //获取类中属性数组
        Field[] fs = demoClass1.getDeclaredFields();
        StringBuilder sb = new StringBuilder();
        sb.append(Modifier.toString(demoClass1.getModifiers()) + " class " + demoClass1.getSimpleName() + "{\n");//里边的每一个属性
        for (Field field : fs) {
            sb.append("\t");//空格
            sb.append(Modifier.toString(field.getModifiers()) + " ");//获得属性的修饰符,例如public,static等等
            sb.append(field.getType().getSimpleName() + " ");//属性的类型的名字
            sb.append(field.getName() + ";\n");//属性的名字+回车
        }
        sb.append("}");
        System.out.println(sb);


        //获取id的属性
        Field idF = null;
        try {
            idF = demoClass1.getDeclaredField("id");
            //打破封装
            //使用反射机制可以打破封装性,导致了java对象的属性不安全
            idF.setAccessible(true);
            //给object对象的id属性赋值110
            idF.set(object, 110); //set
            System.out.println(idF.get(object));//get
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Java 反射机制学习笔记_第1张图片

反射机制可以让我们可以通过获得类的各种内容,进行了反编译。
对于JAVA这种先编译再运行的语言来说,反射机制可以使代码更加灵活,更加容易实现面向对象。

参考:

http://blog.csdn.net/liujiahan629629/article/details/18013523

http://www.cnblogs.com/lzq198754/p/5780331.html

你可能感兴趣的:(Java笔记)