@@ -323,22 +323,23 @@ printArray( stringArray );
323
323
324
324
## 反射
325
325
326
- ### 何为反射?
326
+ 关于反射的详细解读,请看这篇文章 [ Java 反射机制详解 ] ( ./reflection.md ) 。
327
327
328
- 如果说大家研究过框架的底层原理或者咱们自己写过框架的话,一定对反射这个概念不陌生。
328
+ ### 何谓反射?
329
329
330
- 反射之所以被称为框架的灵魂,主要是因为它赋予了我们在运行时分析类以及执行类中方法的能力。通过反射你可以获取任意一个类的所有属性和方法,你还可以调用这些方法和属性。
330
+ 如果说大家研究过框架的底层原理或者咱们自己写过框架的话,一定对反射这个概念不陌生。 反射之所以被称为框架的灵魂,主要是因为它赋予了我们在运行时分析类以及执行类中方法的能力。通过反射你可以获取任意一个类的所有属性和方法,你还可以调用这些方法和属性。
331
331
332
- ### 反射机制优缺点
332
+ ### 反射的优缺点?
333
333
334
- - ** 优点** : 可以让咱们的代码更加灵活、为各种框架提供开箱即用的功能提供了便利
335
- - ** 缺点** :让我们在运行时有了分析操作类的能力,这同样也增加了安全问题。比如可以无视泛型参数的安全检查(泛型参数的安全检查发生在编译时)。另外,反射的性能也要稍差点,不过,对于框架来说实际是影响不大的。[ Java Reflection: Why is it so slow?] ( https://stackoverflow.com/questions/1392351/java-reflection-why-is-it-so-slow )
334
+ 反射可以让我们的代码更加灵活、为各种框架提供开箱即用的功能提供了便利。
336
335
337
- ### 反射的应用场景
336
+ 不过,反射让我们在运行时有了分析操作类的能力的同时,也增加了安全问题,比如可以无视泛型参数的安全检查(泛型参数的安全检查发生在编译时)。另外,反射的性能也要稍差点,不过,对于框架来说实际是影响不大的。
338
337
339
- 像咱们平时大部分时候都是在写业务代码,很少会接触到直接使用反射机制的场景 。
338
+ 相关阅读: [ Java Reflection: Why is it so slow? ] ( https://stackoverflow.com/questions/1392351/java-reflection-why-is-it-so-slow ) 。
340
339
341
- 但是,这并不代表反射没有用。相反,正是因为反射,你才能这么轻松地使用各种框架。像 Spring/Spring Boot、MyBatis 等等框架中都大量使用了反射机制。
340
+ ### 反射的应用场景?
341
+
342
+ 像咱们平时大部分时候都是在写业务代码,很少会接触到直接使用反射机制的场景。但是!这并不代表反射没有用。相反,正是因为反射,你才能这么轻松地使用各种框架。像 Spring/Spring Boot、MyBatis 等等框架中都大量使用了反射机制。
342
343
343
344
** 这些框架中也大量使用了动态代理,而动态代理的实现也依赖反射。**
344
345
@@ -373,7 +374,9 @@ public class DebugInvocationHandler implements InvocationHandler {
373
374
374
375
## 注解
375
376
376
- ` Annotation ` (注解) 是 Java5 开始引入的新特性,可以看作是一种特殊的注释,主要用于修饰类、方法或者变量。
377
+ ### 何谓注解?
378
+
379
+ ` Annotation ` (注解) 是 Java5 开始引入的新特性,可以看作是一种特殊的注释,主要用于修饰类、方法或者变量,提供某些
377
380
378
381
注解本质是一个继承了` Annotation ` 的特殊接口:
379
382
@@ -389,12 +392,51 @@ public interface Override extends Annotation{
389
392
}
390
393
```
391
394
395
+ JDK 提供了很多内置的注解(比如 ` @Override ` 、` @Deprecated ` ),同时,我们还可以自定义注解。
396
+
397
+ ### 注解的解析方法有哪几种?
398
+
392
399
注解只有被解析之后才会生效,常见的解析方法有两种:
393
400
394
401
- ** 编译期直接扫描** :编译器在编译 Java 代码的时候扫描对应的注解并处理,比如某个方法使用` @Override ` 注解,编译器在编译的时候就会检测当前的方法是否重写了父类对应的方法。
395
402
- ** 运行期通过反射处理** :像框架中自带的注解(比如 Spring 框架的 ` @Value ` 、` @Component ` )都是通过反射来进行处理的。
396
403
397
- JDK 提供了很多内置的注解(比如 ` @Override ` 、` @Deprecated ` ),同时,我们还可以自定义注解。
404
+ ## SPI
405
+
406
+ 关于 SPI 的详细解读,请看这篇文章 [ Java SPI 机制详解] ( ./spi.md ) 。
407
+
408
+ ### 何谓 SPI?
409
+
410
+ SPI 即 Service Provider Interface ,字面意思就是:“服务提供者的接口”,我的理解是:专门提供给服务提供者或者扩展框架功能的开发者去使用的一个接口。
411
+
412
+ SPI 将服务接口和具体的服务实现分离开来,将服务调用方和服务实现者解耦,能够提升程序的扩展性、可维护性。修改或者替换服务实现并不需要修改调用方。
413
+
414
+ 很多框架都使用了 Java 的 SPI 机制,比如:Spring 框架、数据库加载驱动、日志接口、以及 Dubbo 的扩展实现等等。
415
+
416
+ ![ ] ( https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/github/javaguide/java/basis/spi/22e1830e0b0e4115a882751f6c417857tplv-k3u1fbpfcp-zoom-1.jpeg )
417
+
418
+ ### SPI 和 API 有什么区别?
419
+
420
+ ** 那 SPI 和 API 有啥区别?**
421
+
422
+ 说到 SPI 就不得不说一下 API 了,从广义上来说它们都属于接口,而且很容易混淆。下面先用一张图说明一下:
423
+
424
+ ![ ] ( https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/github/javaguide/java/basis/spi/1ebd1df862c34880bc26b9d494535b3dtplv-k3u1fbpfcp-watermark.png )
425
+
426
+ 一般模块之间都是通过通过接口进行通讯,那我们在服务调用方和服务实现方(也称服务提供者)之间引入一个“接口”。
427
+
428
+ 当实现方提供了接口和实现,我们可以通过调用实现方的接口从而拥有实现方给我们提供的能力,这就是 API ,这种接口和实现都是放在实现方的。
429
+
430
+ 当接口存在于调用方这边时,就是 SPI ,由接口调用方确定接口规则,然后由不同的厂商去根绝这个规则对这个接口进行实现,从而提供服务。
431
+
432
+ 举个通俗易懂的例子:公司 H 是一家科技公司,新设计了一款芯片,然后现在需要量产了,而市面上有好几家芯片制造业公司,这个时候,只要 H 公司指定好了这芯片生产的标准(定义好了接口标准),那么这些合作的芯片公司(服务提供者)就按照标准交付自家特色的芯片(提供不同方案的实现,但是给出来的结果是一样的)。
433
+
434
+ ### SPI 的优缺点?
435
+
436
+ 通过 SPI 机制能够大大地提高接口设计的灵活性,但是 SPI 机制也存在一些缺点,比如:
437
+
438
+ - 遍历加载所有的实现类,这样效率还是相对较低的;
439
+ - 当多个 ` ServiceLoader ` 同时 ` load ` 时,会有并发问题。
398
440
399
441
## I/O
400
442
@@ -472,3 +514,6 @@ Java IO 流共涉及 40 多个类,这些类看上去很杂乱,但实际上
472
514
问题本质想问:** 不管是文件读写还是网络发送接收,信息的最小存储单元都是字节,那为什么 I/O 流操作要分为字节流操作和字符流操作呢?**
473
515
474
516
回答:字符流是由 Java 虚拟机将字节转换得到的,问题就出在这个过程还算是非常耗时,并且,如果我们不知道编码类型就很容易出现乱码问题。所以, I/O 流就干脆提供了一个直接操作字符的接口,方便我们平时对字符进行流操作。如果音频文件、图片等媒体文件用字节流比较好,如果涉及到字符的话使用字符流比较好。
517
+
518
+
519
+
0 commit comments