Java反射机制

Java反射机制

1、反射的概述

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

要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法。所以先要获取到每一个字节码文件对应的Class类型的对象。

使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码)

2、反射机制的相关类在哪个包

java.lang.reflect.*;

3、反射能做什么?   

  我们知道反射机制允许程序在运行时取得任何一个已知名称的class的内部信息,包括包括其modifiers(修饰符),fields(属性),methods(方法)等,并可于运行时改变fields内容或调用methods。那么我们便可以更灵活的编写代码,代码可以在运行时装配,无需在组件之间进行源代码链接,降低代码的耦合。

先获取Class才能获取Method、Constructor、Field

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

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

类加载:Class对象的由来是将class文件读入内存,并为之创建一个Class对象。

4、反射的具体实现

package com.chen.service;

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

BookServiceImpl 类 实现BookService 接口:

package com.chen.service.impl;

import com.chen.dao.BookDao;
import com.chen.dao.impl.BookDaoImpl;
import com.chen.service.BookService;

public class BookServiceImpl implements BookService {
//类的属性--存储数据
     //公有属性
    public String name;
    
    int age;
    //受保护属性
    protected String sex;
     //私有属性
    private String address;

    //类的构造方法--用来构造对象
    public BookServiceImpl() {
    }

    public BookServiceImpl(String name){

    }

    public 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();
    }

    @Override
    public void fun() {
        System.out.println("BookServiceImpl..fun");
    }
}

spring.properties 外部配置:

key=value

更改java程序需要

修改代码--编译--打包--部署--重启

反射在外修改外部配置 不用重新编译重启

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

1>获取Class的三种方式

注:以上三种方式返回值都是Class类型

//1、通过对象调用 getClass() 方法来获取,通常应用在:比如你传过来一个 Object类型的对象,而我不知道你具体是什么类,用这种方法   
Person p1 = new Person(); Class c1 = p1.getClass();
//2、直接通过 类名.class 的方式得到,该方法最为安全可靠,程序性能更高这说明任何一个类都有一个隐含的静态成员变量 class
 Class c2 = Person.class; //3、通过 Class 对象的 forName() 静态方法来获取,用的最多,但可能抛ClassNotFoundException 异常
 Class c3 = Class.forName("com.ys.reflex.Person");

注意:在运行期间,一个类,只有一个Class对象产生。

2>通过 Class 类获取成员变量、成员方法、接口、超类、构造方法等

查阅 API 可以看到 Class 有很多方法:

  getName():获得类的完整名字。

  getFields():获得类的public类型的属性。

  getDeclaredFields():获得类的所有属性。包括private 声明的和继承类

  getMethods():获得类的public类型的方法。

  getDeclaredMethods():获得类的所有方法。包括private 声明的和继承类

  getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes 参数指定方法的参数类型。

  getConstructors():获得类的public类型的构造方法。

  getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型。

  newInstance():通过类的不带参数的构造方法创建这个类的一个对象。

测试类:
package com.chen.servlet;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

/**
 * 反射的应用
 */

public class Test01 {
    public static void main(String[] args) throws Exception {
        //通过全类名加载类的Class对象
        Class cla = Class.forName("com.chen.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();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }
        System.out.println("-----------------");
        Constructor[] constructors1 = cla.getDeclaredConstructors();
        for (Constructor constructor : constructors1) {
            System.out.println(constructor);
        }
    }

}
package com.chen.servlet;

import com.chen.service.BookService;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.util.Properties;

/**
 * 微型框架
 */

/*
 * 通过Class对象可以获取某个类中的:构造方法、成员变量、成员方法;并访问成员;
 * 
 * 1.获取构造方法:
 *         1).批量的方法:
 *             public Constructor[] getConstructors():所有"公有的"构造方法
            public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)
     
 *         2).获取单个的方法,并调用:
 *             public Constructor getConstructor(Class... parameterTypes):获取单个的"公有的"构造方法:
 *             public Constructor getDeclaredConstructor(Class... parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有;
 *         
 *             调用构造方法:
 *             Constructor-->newInstance(Object... initargs)
 */
public class Test02 {
    public static void main(String[] args) throws Exception {
        //读取配置文件,获取内容
//        File file=new File("D:\\code\\IdeaProjects\\spring2105\\spring01\\src\\info.properties");
//        InputStream stream=new FileInputStream(file);
        InputStream stream = Test02.class.getClassLoader().getResourceAsStream("spring.properties");

        Properties p=new Properties();
        p.load(stream);
        String className=p.getProperty("className");

        //1.通过全类名获取类的Class对象
        Class cla = Class.forName(className);
        //2.通过Class对象获取类的无参构造器
        Constructor constructor = cla.getDeclaredConstructor();
        //3.使用构造器创建对象
        BookService bookService = (BookService) constructor.newInstance();
        //4.使用对象调用方法
        bookService.add();
    }
}
package com.chen.servlet;

import com.chen.service.BookService;

import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Properties;

public class Test03 {
    public static void main(String[] args) throws Exception {
        //读取配置文件,获取内容
//        File file=new File("D:\\code\\IdeaProjects\\spring2105\\spring01\\src\\info.properties");
//        InputStream stream=new FileInputStream(file);
        InputStream stream = Test02.class.getClassLoader().getResourceAsStream("spring.properties");

        Properties p=new Properties();
        p.load(stream);
        String className=p.getProperty("className");
        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中的一种重要机制,它使得Java更灵活

  • 常用的JavaEE框架——Spring全家桶底层都利用了反射机制

  • Spring中spring.properties就是反射的一种利用

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱吃汉堡的代码人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值