java实验4 反射机制

要求:

1)严禁上网抄袭、互相抄袭和各种形式的抄袭(如代码抄袭,运行截图一图多用),一旦发现单次作业按零分处理

2)课程报告正文内容基本格式为:宋体,小五号,1.5 倍行距。

3)作业报告请务必保持排版的整洁规范,排版混乱者将直接判为不及格。

4)为避免办公软件兼容性导致的显示差异问题,要求在提交课程报告 WORD 文件的同

时提交相应的 PDF 版本。

一、实验目的

1. 掌握通过反射动态加载类、创建实例、访问和修改对象的私有字段、调用对象的方法等操作。

2. 掌握如何通过反射获取注解的操作。

3. 掌握反射与设计模式的使用。

  • 实验内容

public class Student {

    private String name;

    private int age;

    public Student() {

        this.name = "Unknown";

        this.age = 0;

    }

    public Student(String name, int age) {

        this.name = name;

        this.age = age;

    }

    public String getName() {

        return name;

    }

    public int getAge() {

        return age;

    }

    public void displayInfo() {

        System.out.println("Name: " + name + ", Age: " + age);

    }

    private void privateMethod() {

        System.out.println("Private method called");

    }

}

  1. 使用反射对类进行相关的操作。创建一个简单类 Student包含私有字段 name 和 age。包含一个无参构造方法和一个带参构造方法。包含公共方法 getName()、getAge() 和 displayInfo()。包含一个私有方法 privateMethod()。

  1. 使用反射机制动态加载 Student 类。
  2. 使用反射机制创建 Student 类的实例。
  3. 使用反射机制访问和修改 Student 类的私有字段。
  4. 使用反射机制调用 Student 类的公共方法和私有方法。

代码:

import java.lang.reflect.Constructor;

import java.lang.reflect.Field;

import java.lang.reflect.Method;

public class ReflectionExample {

    public static void main(String[] args) {

        try {

            // 动态加载Student类

            Class<?> studentClass = Class.forName("Student");

            // 使用无参构造函数创建Student实例

            Student student1 = (Student) studentClass.getDeclaredConstructor().newInstance();

            // 使用带参构造函数创建Student实例

            Constructor<?> constructor = studentClass.getDeclaredConstructor(String.class, int.class);

            Student student2 = (Student) constructor.newInstance("晓晓", 25);

            // 访问和修改私有字段

            Field nameField = studentClass.getDeclaredField("name");

            nameField.setAccessible(true);

            nameField.set(student2, "晓晓");

            Field ageField = studentClass.getDeclaredField("age");

            ageField.setAccessible(true);

            ageField.setInt(student2, 20);

            // 调用公共方法

            Method displayInfoMethod = studentClass.getMethod("displayInfo");

            displayInfoMethod.invoke(student2);

            // 调用私有方法

            Method privateMethod = studentClass.getDeclaredMethod("privateMethod");

            privateMethod.setAccessible(true);

            privateMethod.invoke(student2);

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

}

运行截图:

  1. 有如下场景:项目的持久化层需要使用到的数据库有Redis、MySql、MongoDB。

要求:

  1. 定义一个DataService接口,接口提供add()、delete()、update()、find()四个接口,对应各种数据库的增删改查操作。
  2. 分别实现RedisDataService、MySqlDataService、MongoDBDataService。
  3. 通过反射机制,实现动态工厂模式
  4. 从配置文件中读取需要使用的数据库名称,如redis对应“RedisDataService”、MySql对应“MySqlDataService”、MongoDB对应“MySqlDataService”
  5. 实例化配置文件中所配置的数据库服务对象

其中项目的数据库至少需要选择一种,可选择多种;

配置文件格式如下,则代表项目需要两种类型的数据库,需要创建两个实例。

MySql:MySqlDataService

MongoDB: MySqlDataService

代码:

public interface DataService {

    void add();

    void delete();

    void update();

    void find();

}

public class RedisDataService implements DataService {

    public void add() { System.out.println("Adding via Redis"); }

    public void delete() { System.out.println("Deleting via Redis"); }

    public void update() { System.out.println("Updating via Redis"); }

    public void find() { System.out.println("Finding via Redis"); }

}

public class MySqlDataService implements DataService {

    public void add() { System.out.println("Adding via MySQL"); }

    public void delete() { System.out.println("Deleting via MySQL"); }

    public void update() { System.out.println("Updating via MySQL"); }

    public void find() { System.out.println("Finding via MySQL"); }

}

public class MongoDBDataService implements DataService {

    public void add() { System.out.println("Adding via MongoDB"); }

    public void delete() { System.out.println("Deleting via MongoDB"); }

    public void update() { System.out.println("Updating via MongoDB"); }

    public void find() { System.out.println("Finding via MongoDB"); }

}

import java.util.Properties;

public class DataServiceFactory {

    public static DataService getDataService(String serviceName) {

        try {

            Class<?> clazz = Class.forName(serviceName);

            return (DataService) clazz.getDeclaredConstructor().newInstance();

        } catch (Exception e) {

            e.printStackTrace();

            return null;

        }

    }

}

  MySql=MySqlDataService

MongoDB=MongoDBDataService

import java.io.FileInputStream;

import java.util.Properties;

public class Application {

    public static void main(String[] args) {

        try {

            Properties properties = new Properties();

            properties.load(new FileInputStream("config.properties"));

            for (String key : properties.stringPropertyNames()) {

                String className = properties.getProperty(key);

                DataService service = DataServiceFactory.getDataService(className);

                if (service != null) {

                    service.add();

                    service.delete();

                    service.update();

                    service.find();

                }

            }

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

}

运行截图:

  1. 通过反射和注解,自动生成接口文档。

public class UserController {

public static class UserDTO {

@ApiModelProperty("用户id")

Integer userId;

@ApiModelProperty("用户名称")

String name ;

}

public static class UserVO {

@ApiModelProperty("用户id")

Integer userId;

@ApiModelProperty("用户名称")

String name;

@ApiModelProperty("手机号")

String phone;

}

@PostMapping("/get_user")

public UserVO conf(UserDTO dto) {

return new UserVO();

}

}

@Target(ElementType.FIELD)

@Retention(RetentionPolicy.RUNTIME)

@Documented

public @interface ApiModelProperty {

// 字段的注释

public String value() default "";

}

要求:

  1. 实现自定义注解ApiModelProperty,用于字段描述。
  2. 实现自定义注解PostMapping,用于注明请求方法。
  3. UserDTO代表请求参数,UserVO对应响应参数。
  4. 使用反射机制获取注解信息,并生成一个接口文档,格式如下:

地址: http://localhost:8080/get_user

方法: post

请求参数:

     字段名    类型        注释

     userId     integer     用户id

     name      string      用户名称

返回参数:

    字段名    类型          注释

    userId     integer        用户id

    Name     string         用户名称

    phone     string         用户名称

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

@Target(ElementType.FIELD)

@Retention(RetentionPolicy.RUNTIME)

public @interface ApiModelProperty {

    String value() default "";

}

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

public @interface PostMapping {

    String value() default "";

}

import java.lang.reflect.Field;

import java.lang.reflect.Method;

public class ApiDocumentationGenerator {

    public static void generateDocumentation(Class<?> controllerClass) {

        Method[] methods = controllerClass.getDeclaredMethods();

        for (Method method : methods) {

            if (method.isAnnotationPresent(PostMapping.class)) {

                PostMapping postMapping = method.getAnnotation(PostMapping.class);

                System.out.println("地址: http://localhost:8080" + postMapping.value());

                System.out.println("方法: post");

                Class<?>[] parameterTypes = method.getParameterTypes();

                if (parameterTypes.length > 0) {

                    System.out.println("请求参数:");

                    System.out.println("     字段名    类型        注释");

                    printFields(parameterTypes[0]);

                }

                Class<?> returnType = method.getReturnType();

                System.out.println("返回参数:");

                System.out.println("     字段名    类型          注释");

                printFields(returnType);

            }

        }

    }

    private static void printFields(Class<?> clazz) {

        Field[] fields = clazz.getDeclaredFields();

        for (Field field : fields) {

            ApiModelProperty apiModelProperty = field.getAnnotation(ApiModelProperty.class);

            if (apiModelProperty != null) {

                System.out.println("    " + field.getName() + "     " + field.getType().getSimpleName().toLowerCase() + "        " + apiModelProperty.value());

            }

        }

    }

    public static void main(String[] args) {

        generateDocumentation(UserController.class);

    }

}

三、思考题

1. 反射机制实现动态代理的原理是什么?

     反射机制实现动态代理的原理是在运行时创建代理类和对象,通过代理对象拦截对真实对象方法的调用,并允许在调用前后执行特定操作。这是通过 `java.lang.reflect.Proxy` 类和 `InvocationHandler` 接口实现的。                       

  1. 简述简单工厂设计模式与动态工厂设计模式的区别?

       简单工厂设计模式是创建型模式,通过一个工厂类来创建不同类型的对象,客户端与具体产品解耦。动态工厂设计模式是简单工厂的扩展,它使用一个工厂方法来创建对象,允许在运行时动态决定创建何种产品。简单工厂在添加新产品时需要修改工厂类,而动态工厂通过继承或接口实现避免了这一点。                                  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/501756.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

简易Type-C拉取5V/3A电流电路分享

今天介绍一种在Type-C 5V电压下获取3A电流的简易办法 我们都知道&#xff0c;USB里面的D D-用来传输数据&#xff0c;其实Type-C接口里面还有一组CC引脚&#xff0c;先科普一些概念 DFP&#xff0c;下行端口&#xff0c;可以理解为Host&#xff0c;数据下行以及对外提供电源&…

基于Spring Boot的IT技术交流和分享平台的设计与实现源码

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的IT技术交流和分享平台的设计与实现。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 基于S…

海南省大数据发展中心:数据资产场景化评估案例手册(第二期)

2025年1月3日&#xff0c;海南省数据产品超市印发《数据资产场景化评估案例手册&#xff08;第二期&#xff09;》&#xff08;以下简称《手册》&#xff09;&#xff0c;该手册是基于真实数据要素典型应用场景进行数据资产评估操作的指导性手册&#xff0c;为企业在数据资产入…

​​​​​​​CDP集群安全指南系列文章导读

[一]大数据安全综述 1-认证 身份验证是任何计算环境的基本安全要求。简单来说&#xff0c;用户和服务必须在使用系统功能并获得授权之前&#xff0c;向系统证明其身份&#xff08;进行身份验证&#xff09;。身份验证与授权紧密配合&#xff0c;共同保护系统资源。大多数 CDH …

Chapter4.2:Normalizing activations with layer normalization

文章目录 4 Implementing a GPT model from Scratch To Generate Text4.2 Normalizing activations with layer normalization 4 Implementing a GPT model from Scratch To Generate Text 4.2 Normalizing activations with layer normalization 通过层归一化&#xff08;La…

MyBatis-plus sql拦截器

因为业务需求&#xff0c;重新写了一套数据权限。项目中用的是mybtis-plus&#xff0c;正好MyBatis-Plus提供了插件数据权限插件 | MyBatis-Plus&#xff0c;那就根据文档来实现这个需求。 实现&#xff1a; 实现MultiDataPermissionHandler 首先创建MultiDataPermissionHan…

数据挖掘——关联规则挖掘

数据挖掘——关联数据挖掘 关联数据挖掘关联规则关联规则挖掘问题&#xff1a;具体挖掘过程Apriori 产生关联规则 关联数据挖掘 关联分析用于发现隐藏在大型数据集中的令人感兴趣的联系&#xff0c;所发现的模式通常用关联规则或频繁项集的形式表示。 关联规则反映一个事物与…

启航数据结构算法之雅舟,悠游C++智慧之旅——线性艺术:顺序表之细腻探索

人无完人&#xff0c;持之以恒&#xff0c;方能见真我&#xff01;&#xff01;&#xff01; 共同进步&#xff01;&#xff01; 文章目录 一、线性表的概念二、顺序表1.概念与结构2.顺序表的分类静态顺序表动态顺序表 三、顺序表的实现1.顺序表的结构2.顺序表的初始化和销毁初…

数据库进阶教程之DDL语句(万字详解)

文章目录 一、数据库操作-上1.1、DDL概述1.2、创建数据库1.3、查看数据库 二、数据库操作-下2.1、修改数据库2.2、删除数据库2.3、使用数据库 三、数据库表操作-上3.1、创建表3.2、数据类型&#xff08;mysql&#xff09;3.3、查看表 四、数据库表操作-中4.1、快速建表4.2、删除…

自动驾驶三维重建

大概八成估计是未来的科研方向了 文章目录 自动驾驶中的NeRF[4]CLONeR&#xff1a;Urban Radiance Fields[6]S-NERFBlock-NeRFSwitch-NeRFSceneRFBehind the Scenes 大规模与自动驾驶场景重建:3D高斯VastGaussianPeriodic Vibration Gaussian&#xff08;复旦大学&#xff09;…

OWASP ZAP之API 请求基础知识

ZAP API 提供对 ZAP 大部分核心功能的访问,例如主动扫描器和蜘蛛。ZAP API 在守护进程模式和桌面模式下默认启用。如果您使用 ZAP 桌面,则可以通过访问以下屏幕来配置 API: Tools -> Options -> API。 ZAP 需要 API 密钥才能通过 REST API 执行特定操作。必须在所有 …

【小程序开发】- 小程序版本迭代指南(版本发布教程)

一&#xff0c;版本号 版本号是小程序版本的标识&#xff0c;通常由一系列数字组成&#xff0c;如 1.0.0、1.1.0 等。版本号的格式通常是 主版本号.次版本号.修订号 主版本号&#xff1a;当小程序有重大更新或不兼容的更改时&#xff0c;主版本号会增加。 次版本号&#xff1a…

电子应用设计方案85:智能 AI门前柜系统设计

智能 AI 门前柜系统设计 一、引言 智能 AI 门前柜系统旨在提供便捷、安全和智能的物品存储与管理解决方案&#xff0c;适用于家庭、公寓或办公场所的入口区域。 二、系统概述 1. 系统目标 - 实现无接触式物品存取&#xff0c;减少交叉感染风险。 - 具备智能识别和分类功能&am…

CG顶会论文阅读|《科技论文写作》硕士课程报告

文章目录 一、基本信息1.1 论文基本信息1.2 课程基本信息1.3 博文基本信息 二、论文评述&#xff08;中英双语&#xff09;2.1 研究问题&#xff08;Research Problem&#xff09;2.2 创新点&#xff08;Innovation/Contribution&#xff09;2.3 优点&#xff08;Why this pape…

Deepseek v3 的笔记

基本概述 Deepseek v3是Deepseek发布的旗舰模型&#xff0c;属于607B的混合专家&#xff08;MoE&#xff09;模型&#xff0c;其中活跃参数为37B。在当前的模型领域&#xff0c;它堪称最佳的开源模型&#xff0c;性能超越了Llama 3.1 405b、Qwen和Mistral等知名模型。根据基准…

基于单片机的家庭智能垃圾桶(论文+源码)

1系统整体方案设计 本次课题为基于单片机的家庭智能垃圾桶&#xff0c;在此将目标功能设计如下&#xff1a; &#xff08;1&#xff09;实现垃圾桶的智能开关盖当检测到有人停留三秒以上自动开启&#xff0c;并当人走后自动关闭开关盖&#xff1b; &#xff08;2&#xff0…

Niushop商城商业插件_cps联盟_包装转换_视频购物_同城配送_上门预约等插件的安装方法

一.简介 使用Niushop已经多年&#xff0c;积累下很多有用的常识&#xff0c;有人让我评价下这个系统&#xff01;怎么说呢&#xff01;系统是好系统因为它开源&#xff01;且更新也很及时几乎是一周一更新&#xff0c;开发团队也很尽职&#xff0c;在用户群内得到很高的评价&am…

一文讲清楚HTTP常见的请求头和应用

文章目录 一文讲清楚HTTP常见的请求头和应用1. 啥是个HTTP请求头2. 常见的请求头&#xff0c;作用和示例3.协商缓存4.会话状态 一文讲清楚HTTP常见的请求头和应用 1. 啥是个HTTP请求头 一句话&#xff0c;说白了就是限定HTTP传输的一些规则参数&#xff0c;比如Accept&#xf…

vim 的基础使用

目录 一&#xff1a;vim 介绍二&#xff1a;vim 特点三&#xff1a;vim 配置四&#xff1a;vim 使用1、vim 语法格式2、vim 普通模式&#xff08;1&#xff09;保存退出&#xff08;2&#xff09;光标跳转&#xff08;3&#xff09;文本删除&#xff08;4&#xff09;文本查找&…

RocketMQ面试题:进阶部分

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…