Java反射

一、反射的概述

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象. 

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

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

 2.获取Class的三方式

要操作一个类的字节码,需要首先获取到这个类的字节码,怎么获取java.lang.Class实例?

方式 备注
Class.forName(“完整类名带包名”) 静态方法
对象.getClass()
任何类型.class
public class Demo{
    public static void main(String[] args) throws Exception {
        //获取Class对象的第一种方式:
        Student student = new Student();
        Class c1 = Class.forName("Day01.test01.Student");
        System.out.println("第一种方式:"+c1.getMethods());
        //第二种方式:
        Class c2 = Student.class;
        System.out.println("第二种方式:"+c2.getMethods());
        //第三种方式:
        Class c3 = student.getClass();
        System.out.println("第三种方式:"+c3.getMethods());
    }
}

3.反射

        Class cla = null;
        //获取Class对象的引用
        cla = Class.forName("Day01.test01.Student");

        //第一种方法,实例化默认构造方法,Student必须无参构造函数,否则将抛异常
        Student student = (Student) cla.newInstance();
        student.setAge(20);
        student.setName("java");
        System.out.println(user);

两段代码执行效果一样,但是实现的过程还是有很大的差别的:

第一段代码在未运行前就已经知道了要运行的类是 Student ;
第二段代码则是到整个程序运行的时候,从字符串 “Day01.test01.Student”,才知道要操作的类是 Student 。
所以反射就是在运行时才知道要操作的类是什么,并且可以在运行时获取类的完整构造,并调用对应的方法。

4.反射的应用

Class对象中一些方法的使用

        先写一个接口和两个接口的实现类

        BookService 接口

public interface BookService {
    public void add();
 
    public void fun();
}

BookServiceImpl实现类

public class BookServiceImpl implements BookService {
    //类的属性---存储数据
    public String name;
    int age;
    protected String sex;
    private String address;
 
    //类的构造方法---用来构造对象
    public BookServiceImpl() {
    }
 
    public BookServiceImpl(String name) {
        this.name = name;
    }
 
    private BookServiceImpl(String name, int age, String sex, String address) {
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.address = address;
    }
 
 
    BookDao bookDao=new BookDaoImpl();
 
    //功能方法---完成一些程序或者功能
    @Override
    public void add() {
        System.out.println("BookServiceImpl...add");
        bookDao.add();
    }
 
    public void fun(){
        System.out.println("BookServiceImpl...fun");
    }
}

BookServiceVip实现类


public class BookServiceVip implements BookService {
    BookDao bookDao=new BookDaoImpl();
    @Override
    public void add() {
        System.out.println("BooKServiceVip...add");
        bookDao.add();
    }
 
    public void fun(){
        System.out.println("BookServiceImpl...fun");
    }
}

在测试类Class中的一些常用的方法

    public class Test01 {
    public static void main(String[] args) throws Exception {
        //通过全类名加载类的Class对象
        Class cla = Class.forName("com.w.service.impl.BookServiceImpl");
        //Class对象可以认为是类的手术刀,可以解刨类里面的东西--属性、构造器、方法
        Field[] fields = cla.getFields(); //只能获取public修饰的属性
        for (Field field : fields) {
            System.out.println(field);
        }
        System.out.println("-------------");
        Field[] fields1 = cla.getDeclaredFields(); //获取所有属性
        for (Field field : fields1) {
            System.out.println(field);
        }
 
        System.out.println("======================");
 
        Constructor[] constructors = cla.getConstructors();//获取构造该方法(public修饰的方法)
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }
        System.out.println("-------------");
        Constructor[] constructors1 = cla.getDeclaredConstructors();//获取所有的构造方法
        for (Constructor constructor : constructors1) {
            System.out.println(constructor);
        }
 
        System.out.println("======================");
        Method[] methods = cla.getMethods();//获取所有public修饰的方法
        for (Method method : methods) {
            System.out.println(method);
        }
        System.out.println("-------------");
        Method[] methods1 = cla.getDeclaredMethods();//获得类的所有方法。包括private 声明的和继承类
        for (Method method : methods1) {
            System.out.println(method);
        }
    }
}

使用外部配置和反射机制完成一个微型框架

1、在src目录下新建一个properties文件

2、其中数据和值采用键值对(key = value)的形式进行赋值

className=com.chen.service.impl.BookServiceVip
methodName=add

3、在测试类中完成框架内容


   InputStream stream=Test01.class.getClassLoader().getResourceAsStream("info.properties");
        //声明一个properties对象
        Properties p=new Properties();
        p.load(stream);
        String className=p.getProperty("className");//想要获取的值的key
        String methodName=p.getProperty("methodName");
 
        //1.通过全类名获取类的Class对象
        Class cla = Class.forName(className);
        //2.通过Class对象获取类的无参构造器
        Constructor constructor = cla.getDeclaredConstructor();
        //3.使用构造器创建对象
        BookService bookService = (BookService) constructor.newInstance();
        //4.获取方法名
        Method method = cla.getDeclaredMethod(methodName);
        //5.执行方法
        method.invoke(bookService);
    }
}

你可能感兴趣的:(java,jvm,开发语言)