# xueqi4-2404-parent **Repository Path**: coder_chenjun/xueqi4-2404-parent ## Basic Information - **Project Name**: xueqi4-2404-parent - **Description**: 2404-java - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-03-20 - **Last Updated**: 2026-04-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 反射 如果项目写好了,打包了,想实例化一个对象 ```java Student s = new Student(); ``` 或者两个文本框让用户输入,一个输入类名,一个输入方法点,点击一个按钮让类的方法得到执行 现有的java知识做不到上面的需求,只有反射可以 反射:运行的时候剖析类的情况,并操作类的成员 常识: 类的信息有以下几类 - 类本身的信息 - 类名 - 类所在的包 - 类的修饰符(public) - 类的父类 - 类的所有实现的接口 - 成员 - 字段 - 构造函数 - 方法 成员分为两位 - 静态的 - 实例 成员的来源 - 自己写 - 从父继承的 英文基础常识 - Class:类 - Field:字段 - Method:方法 - Constructor:构造函数 - Declared:声明,在反射的语境里 自己写的东西,比如方法 - instance:实例(new出来的对象 反射代码的写法一般 - 获取Class对象 - 获取成员 - 操作成员 ```java Class clz =....; Method m = clz.getDeclaredMethod(); m.invoe ``` ## 反射练习 - 设计一个方法,自动生成sql并把对象作为记录插入到数据库 ```java public void insert(Userinfo ui) { } ``` - 实现bean拷贝功能,方法签名设计如下,规则:同名属性之间拷贝 ```java public Object copyBean(Object source, Class target) { } Userinfo ui = new Userinfo(); ui. setId(100); ui. setUsername("abc"); User user = copyBean(ui, User.class) ``` - 实现从数据库中查询数据,并自动封装到实体类中 ```java public static Object getData(Connection connection, String sql, Class clz, Object... params) { } User user = getData(conn, "select id,username from user where id=?", User.class, 100) ``` # SPI SPI:service(服务) Provider(提供者) interface(接口) 三个角色 - 服务定义:接口项目 ,契约(Contract),规定需要什么功能,但不实现 - 服务的提供者:也就是上面的接口的实现方,是真正提供功能的人 - 服务的使用者:使用那个功能的人 实现步骤 - 建立一个模块,比如叫spi-parent,这个不是必须,是用来管理三个spi的相关模块用的 - 建立一个接口模块,这个就是服务定义的,这里主要是写功能接口,没有实现类 - 建立一个接口的实现模块,也就是服务提供者,这里就写类来实现上面的接口模块中定义的接口,在此模块中要进行配置:META-INF/services/接口全称的文件名 - 建立一个模块,就是接口的使用一方,建立一个类似的业务类,它里面就会调用接口的服务 # 设计模式(Desgin Pattern) 软件的目标 - 可复用 - 可维护 - 可扩展 达成这个目标就需要高质量的代码,在OOP编程领域就是要遵循面向的设计原则(Principal) 面向的对象的原则有很多个,但主要是五个(简称SOLID) - SRP(single responsible 单一职责原则) - DIP(Dependence Inversion依赖倒转原则) - LSP( Liskov Substitution里氏替换原则) - OCP(open close开闭原则) - ISP(interface seperation接口隔离—— 日常编程工作中,有一些问题,它的解决办法是固定,是模式化的,这些模式化的代码就是设计模式,G4总结了23种 原则是最最重要的,依据它你可以创造出自己的模式 ## 模版方法设计模式 Template Method Design Pattern ## 单例 https://cloud.tencent.com/developer/article/1497592 ### 多线程 - 并行(Parallelism):在同一个时刻,多个事情是同时发生,在计算机领域就真的需要多个cpu或者多核的cpu - 并发(Concurrency):在同一个时段,是多个事情同时发生,但是由于时间片的原因,“感觉”是多个事情在同个时刻同时发生 ## 观察者设计模式(Observer) https://www.cnblogs.com/porotin/p/7825656.html # UML UML:universal Model language(统一建模语言),大概13种图形 ## 类图(Class diagram) ![](images/uml3.jpg) ![](images/uml2.jpg) ![](images/uml1.jpg) ![](images/uml4.jpg) 实战案例 ![](images/classdiagram.png) ## 时序图(sequence diagram) https://www.cnblogs.com/ywqu/archive/2009/12/22/1629426.html ![](images/sequencediagram.png) ## IDEA插件 - IDEA旗舰版自带的Diagrams可以看类图 - 时序图装sequencediagram core和sequencediagram java插件生成时序图 - PlantUml Parser依据代码生成puml文件 - plantuml4idea基于puml文件生成图形 ## 用例图(use case) # dbutils ## 重复代码优化 重复代码优化逻辑 假定A与B两个类里面有重复代码,优化思考逻辑是 1.把重复代码抽取为一个方法,假定在A中操作的,方法名为m1 2.消除重复的逻辑可能 2.1 把m1保留在某一方,另一方引用它 2.2 把m1放在第三方,A与B都引用这个第三方 3.具体实践方法 3.1 m1保留在A中,B与A建立关联关系,直接调用A的m1 3.2 建立A与B的父类,把m1放在父类中 3.3 把m1放在第三方类,比如C中,A与B都与C建立管理 B怎么使用A的方法m1 第一种:如果m1是一个静态方法 ```java class B { void doSth(){ A.m1(); } } ``` 第二种 ```java class B{ void doSth(A a){ a.m1() } } ``` 第三种 ```java class B{ private A a ; public B (A a){ this.a = a; } void doSth(){ a.m1() } } ``` 第四种 ```java class B{ private A a ; public void setA (A a){ this.a = a; } void doSth(){ a.m1() } } ``` # 作业 0.跟上进度,理解 1.我们的ScalarHandler,ScalarListHandler,以及2个Map相关的Handler,其中都有构造函数传递名字和序号的代码,能优化吗?(必做) 2.Apache的dbutils的GenerousRowProcessor怎么用上,明天来教师机写出来(必做) 3 读懂GenerouseRowProcessor宽松了什么?如果列名与字段或者属性名不匹配,apache有提供机制解决这个问题吗?(不允许baidu,也不允许ai) # 接口 - 早期设计里面只能写常量与抽象方法 - 如果你的接口只有一个抽象方法,那么可以在接口上添加@FunctionalInterface,这个注解让编译器确保你的接口不能超过一个抽象 - 默认方法(实例方法) - 静态方法 - 私有方法 - 私有静态 - 私有实例方法 # Lambda ## 基本概念与使用 lambda表达式:其实就是代表一个方法,代表着一个方法指针,因为java这个语言,方法不能独立存在,必须放在类型里面,也就是接口或类里面 所以lambda表达式通常与函数接口一起使用,在java中,所有能用到函数接口的地方就可以用lambda表达式 基本写法要点 - 无参数:()-> 括号是不能省略的 - 有参数时:可以(x,y)->也可以这样写(int x,String y),但不能(x,String y),类型要么都写,要么都不写。如果只有一个参数,小括号也可以省略的 - 方法体:多行代码时必须有大括号()->{},如果只有一行,大括号是可以省略的,方法体只有一行代码时,return语句是可以省略的 - ## 方法引用 ### 逆变(contravariant)与协变(covariant) ## JDK提供的4大类函数接口 Consumer Supplier Predicate Function ### 基本类型(Primitive) 四大函数接口对基本类型的支持,比如IntConsumer,IntSupplier等 ### 各函数接口自带的默认方法 - Consumer的andThen - Function的compose,andThen,identity - Predicate的and,or,negate及静态方法isEqual