——JAVASE-反射

本文介绍了Java反射机制的概念,包括动态获取类信息的能力。详细讲述了通过三种方式获取字节码文件对象,以及如何获取构造函数、字段和方法。反射在需要动态调用类的方法或属性时特别有用,文中也提供了反射的应用示例。
摘要由CSDN通过智能技术生成

一、反射
1、概念
JAVA反射机制是在运行状态中,对于任意一个类(class文件),都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
简而言之,动态获取类中信息就是反射。
2、应用
如果想要对指定名称的字节码文件进行加载并获取其中的内容并调用,这时就使用到了反射技术。
3、获取字节码文件对象的3种方式
想要对一个类文件进行解剖,只要获取到该类的字节码文件对象即可。
获取方式1:使用Object类中的getClass()方法

public static void getClassObject1(){
        Person p=new Person();//创建对象
        Class clazz=p.getClass();
        Person p1=new Person();
        Class clazz1=p1.getClass();
        System.out.println(clazz==clazz1);
    }
使用这种方式,必须明确具体的类,并且创建对象,较为麻烦

获取方式2:使用数据类型的静态属性.class

public static void getClassObject2(){
        Class clazz=Person.class;//.class属性
        Class clazz1=Person.class;
        System.out.println(clazz==clazz1);
    }
    比上一种方式简单,但还是要用到类中的静态方法,不够扩展

获取方式3:Java中提供的类描述字节码文件的类Class中的静态方法forName(String name);

public static void getClassObject3() throws ClassNotFoundException{
        String className="bean.Person";
        Class c=Class.forName(className);
        System.out.println(c);

    }
此方法只要给出类的字符串名称就可以获取该类的字节码文件对象,扩展性非常好。

4、 获取字节码文件中的构造函数、字段、一般函数。
(1)、获取Class对象所表示的类的对象(构造函数Constructor )
早期:
Person p=new Person:
分析:new时,先根据New时类的名称寻找该类的字节码文件对象,并加载进内存,创建该字节码文件对象,并接着创建该字节文件对应的Person对象。
现在:利用java提供的CLass类,根据类的名称直接获取字节码文件对象,并使用Class类中的方法创建该字节码文件对象表示的类的对象。
A.构造函数无参数的情况

public static void getObject1() throws ClassNotFoundException, InstantiationException, IllegalAccessException{
        //例1:Person p=new Person();
        String name="bean.Person";//只需知道类名(包名.类名)
        //找到该文件对应的字节码文件,并加载进内存,并产生class对象
        Class clazz=Class.forName(name);
        //产生字节码文件对应的类的对象
        Object obj=clazz.newInstance();

    }

B.构造函数有参数的情况

public static void getObject2()throws Exception{
        String name="bean.Person";
        //找到该文件对应的字节码文件,并加载进内存,并产生class对象
        Class clazz=Class.forName(name);
        //获取指定的构造函数
        Constructor c=clazz.getConstructor(String.class,int.class);
        //通过构造器对象的newInstance()方法进行对象的初始化
        Object obj=c.newInstance("小明",29);
    }

2、获取字段(Field)

public static void  getFieldDemo()throws Exception{
        String name="bean.Person";
        Class clazz=Class.forName(name);
        Field field=clazz.getDeclaredField("age");//只获取本类中的,但包括私有的
        Object obj=clazz.newInstance();//类文件对象
       field.setAccessible(true);//修改字段的访问权限
        field.set(obj,89);//设置obj对象的字段的新值
        Object o=field.get(obj);//获取Obj对象上的值

        System.out.println(o);      

    }

(3)、获取方法(Method)

   //获取公共方法
    public static void getMethodDemo1() throws Exception{
        Class clazz=Class.forName("bean.Person");
        Method[] methods=clazz.getMethods();// 本类继承类的所有公共方法
        //Method[] methods=clazz.getDeclaredMethods();//只获取本类中的所有方法

        for(Method method:methods)
        {
            System.out.println(method);

        }
}
    //获取指定公共成员方法
    public static void getMethodDemo2() throws Exception{
        Class clazz=Class.forName("bean.Person");
        Method method=clazz.getMethod("show", null);//获取无参方法
        //使用构造函数进行传值
        Constructor cos=clazz.getConstructor(String.class,int.class);
        Object obj=cos.newInstance("xiaoming",21);
        //Object obj=clazz.newInstance();
         method.invoke(obj, null);//运行method对象的底层方法
    }

     //运行带参方法
     public static void getMethodDemo3() throws Exception{
        Class clazz=Class.forName("bean.Person");
        Method method=clazz.getMethod("show", String.class,int.class);
        Object obj=clazz.newInstance();
        method.invoke(obj, "xiaoming",21);
    }

5、反射应用示例

//主板
public class MainBoard {

    public void run(){
        System.out.println("mianboard run");
    }
    public void usePCI(PCI p){
        if(p!=null){
        p.open();
        p.close();
        }

    }
}
//主板对外提供的接口
public interface PCI {
public void open();
public void close();
}
//声卡实现PCI 接口
public class SoundCard implements PCI {
    public void open(){
        System.out.println("soundcard open");
    }
    public void close(){
        System.out.println("soundcard close");
    }

}
//网卡实现PCI 接口
public class NetCard implements PCI {
     public void open() {
        System.out.println("netCard run");
    }
    public void close() {
        System.out.println("netCard close");
    }
}
import java.io.*;
import java.util.Properties;
public class ReflectTest {
  public static void main(String[] args) throws Exception {
        MainBoard  mb=new MainBoard();
        mb.run();
        /*
//每次添加一个设备都要修改代码传递一个新创建的对象,能不能不修改代码就可以完成这个动作
        mb.usePCI(new SoundCard());
        不用new来完成,而是只获取其CLASS文件,在内部实现创建对象的动作
        */
        File config=new File("pci.properties");
        FileInputStream fis=new FileInputStream(config);
        Properties p=new Properties();
        p.load(fis);
        for(int x=0;x<p.size();x++)
        {
            String pciName=p.getProperty("pci"+(x+1));
            Class clazz=Class.forName(pciName);//用class去加载这个pci子类
            PCI pci=(PCI)clazz.newInstance();
            mb.usePCI(pci);

        }
        fis.close();
        }
    }
    配置文件pci.properties:
    pci1=mainDemo.SoundCard
    pci2=mainDemo.NetCard

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值