提交 77e96f07 编写于 作者: 沉默王二's avatar 沉默王二 💬

重新归类

上级 b93f8f06
......@@ -56,26 +56,26 @@
### **概述**
- [什么是 Java](docs/basic/what-is-java.md)
- [Java 发展简史](docs/basic/java-history.md)
- [Java 为什么如此流行](docs/basic/why-java-popular.md)
- [第一个 Java 程序:Hello World](docs/basic/hello-world.md)
- [Java程序在编译期发生了什么](docs/basic/what-happen-when-javac.md)
- [JDK 和 JRE 有什么区别](docs/basic/jdk-jre.md)
- [JVM 是什么](docs/basic/jvm.md)
- [Java 注释:程序的注解](docs/basic/javadoc.md)
- [什么是 Java](docs/overview/what-is-java.md)
- [Java 发展简史](docs/overview/java-history.md)
- [Java 为什么如此流行](docs/overview/why-java-popular.md)
- [第一个 Java 程序:Hello World](docs/overview/hello-world.md)
- [Java程序在编译期发生了什么](docs/overview/what-happen-when-javac.md)
- [JDK 和 JRE 有什么区别](docs/overview/jdk-jre.md)
- [JVM 是什么](docs/overview/jvm.md)
- [Java 注释:程序的注解](docs/overview/javadoc.md)
### **核心语法**
- [一网打尽 Java 的那些关键字](docs/basic/java-keywords.md)
- [Java 运算符有哪些?](docs/basic/java-operator.md)
- [Java 变量类型有哪些](docs/basic/java-var.md)
- [Java 数据类型有哪些](docs/basic/java-data-type.md)
- [技术大佬的必备素质:命名优雅](docs/object-class/java-naming.md)
- [一网打尽 Java 的那些关键字](docs/core-grammar/java-keywords.md)
- [Java 运算符有哪些?](docs/core-grammar/java-operator.md)
- [Java 变量类型有哪些](docs/core-grammar/java-var.md)
- [Java 数据类型有哪些](docs/core-grammar/java-data-type.md)
- [技术大佬的必备素质:命名优雅](docs/core-grammar/java-naming.md)
### **分支、循环**
- [流程控制语句有哪些?图解版](docs/basic/java-control.md)
- [流程控制语句有哪些?图解版](docs/control/java-control.md)
### **字符串**
......@@ -103,22 +103,22 @@
### **关键字详解**
- [学妹必须学会的 static 关键字](docs/object-class/java-static.md)
- [学弟必须掌握的 this 和 super ](docs/object-class/java-this.md)
- [再见了,我的 final 关键字](docs/object-class/java-final.md)
- [判断对象的类型:instanceof 关键字](docs/object-class/java-instanceof.md)
- [学妹必须学会的 static 关键字](docs/keywords/java-static.md)
- [学弟必须掌握的 this 和 super ](docs/keywords/java-this.md)
- [再见了,我的 final 关键字](docs/keywords/java-final.md)
- [判断对象的类型:instanceof 关键字](docs/keywords/java-instanceof.md)
### **关键知识点**
- [必知必会的 Unicode:躲开锟斤拷](docs/basic/unicode.md)
- [傻傻分不清:方法重载和方法重写](docs/object-class/override-overload.md)
- [Java 表示:我只有值传递,没有引用传递](docs/object-class/pass-by-value.md)
- [面试经典题目:浅拷贝与深拷贝有什么区别](docs/object-class/deep-copy.md)
- [自动拆箱与自动装箱,好玩](docs/object-class/box.md)
- [必知必会的 Unicode:躲开锟斤拷](docs/core-points/unicode.md)
- [傻傻分不清:方法重载和方法重写](docs/core-points/override-overload.md)
- [Java 表示:我只有值传递,没有引用传递](docs/core-points/pass-by-value.md)
- [面试经典题目:浅拷贝与深拷贝有什么区别](docs/core-points/deep-copy.md)
- [自动拆箱与自动装箱,好玩](docs/core-points/box.md)
### **反射**
- [深入理解 Java 的反射](docs/object-class/fanshe.md)
- [深入理解 Java 的反射](docs/fanshe/fanshe.md)
### **异常**
......@@ -128,9 +128,12 @@
- [try-with-resouces](docs/exception/try-with-resouces.md)
### **泛型**
- [撸个注解有什么难的](docs/fanxing/annotation.md)
### **注解**
- [撸个注解有什么难的](docs/object-class/annotation.md)
- [撸个注解有什么难的](docs/annotation/annotation.md)
......
......@@ -6,7 +6,7 @@
三妹毫不犹豫地摇摇头,摆摆手,不好意思地承认自己的确没有自定义过。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/object-class/annotation-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/annotation/annotation-01.png)
“好吧,哥来告诉你吧。”
......@@ -224,4 +224,4 @@ public class JsonFieldTest {
**教妹学 Java**》预计一个月左右会有一次内容更新和完善,大家在我的公众号 **沉默王二** 后台回复“**03**” 即可获取最新版!如果觉得内容不错的话,欢迎转发分享!
<img src="https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/itwanger.png" alt="图片没显示的话,可以微信搜索「沉默王二」关注" style="zoom:50%;" />
\ No newline at end of file
<img src="https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/itwanger.png" alt="图片没显示的话,可以微信搜索「沉默王二」关注" style="zoom:50%;" />
\ No newline at end of file
......@@ -95,11 +95,11 @@ for (String s : cmowers) {
`Arrays.toString()` 可以将任意类型的数组转成字符串,包括基本类型数组和引用类型数组。该方法有多种重载形式。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/array/print-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/array/print-01.png)
使用 `Arrays.toString()` 方法来打印数组再优雅不过了,就像,就像,就像蒙娜丽莎的微笑。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/array/print-02.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/array/print-02.png)
(三妹看到这么一副图的时候忍不住地笑了)
......@@ -137,7 +137,7 @@ System.out.println(Arrays.deepToString(deepArray));
“说到打印,三妹,哥给你提醒一点。阿里巴巴的 Java 开发手册上有这样一条规约,你看。”
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/array/print-03.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/array/print-03.png)
“什么是 POJO 呢,就是 Plain Ordinary Java Object 的缩写,一般在 Web 应用程序中建立一个数据库的映射对象时,我们称它为 POJO,这类对象不继承或不实现任何其它 Java 框架的类或接口。”
......@@ -155,4 +155,4 @@ System.out.println(Arrays.deepToString(deepArray));
**教妹学 Java**》预计一个月左右会有一次内容更新和完善,大家在我的公众号 **沉默王二** 后台回复“**03**” 即可获取最新版!如果觉得内容不错的话,欢迎转发分享!
<img src="https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/itwanger.png" alt="图片没显示的话,可以微信搜索「沉默王二」关注" style="zoom:50%;" />
<img src="https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/itwanger.png" alt="图片没显示的话,可以微信搜索「沉默王二」关注" style="zoom:50%;" />
......@@ -6,7 +6,7 @@
### 01、if-else 相关
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/thirteen-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/control/thirteen-01.png)
**1)if 语句**
......@@ -21,7 +21,7 @@ if(布尔表达式){
画个流程图表示一下:
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/thirteen-02.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/control/thirteen-02.png)
来写个示例:
......@@ -57,7 +57,7 @@ if(布尔表达式){
画个流程图表示一下:
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/thirteen-03.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/control/thirteen-03.png)
来写个示例:
......@@ -141,7 +141,7 @@ else{
画个流程图表示一下:
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/thirteen-04.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/control/thirteen-04.png)
来写个示例:
......@@ -184,7 +184,7 @@ if(外侧条件){
画个流程图表示一下:
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/thirteen-05.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/control/thirteen-05.png)
来写个示例:
......@@ -244,7 +244,7 @@ default: // 该关键字是可选项
画个流程图:
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/thirteen-06.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/control/thirteen-06.png)
......@@ -352,7 +352,7 @@ public class SwitchEnumDemo {
### 03、for 循环
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/thirteen-07.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/control/thirteen-07.png)
**1)普通 for 循环**
......@@ -382,7 +382,7 @@ for(初识变量;条件;自增/自减){
画个流程图:
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/thirteen-08.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/control/thirteen-08.png)
......@@ -525,7 +525,7 @@ while(条件){
画个流程图:
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/thirteen-09.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/control/thirteen-09.png)
......@@ -607,7 +607,7 @@ do{
画个流程图:
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/thirteen-10.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/control/thirteen-10.png)
......@@ -674,7 +674,7 @@ public class InfinitiveDoWhileExample {
把 do-while 的条件设置为 true,并且循环体中没有 break 关键字的话,程序一旦运行起来,就根本停不下来了,除非强制停止。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/thirteen-11.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/control/thirteen-11.png)
### 06、break
......@@ -685,7 +685,7 @@ break 关键字通常用于中断循环或 switch 语句,它在指定条件下
来画个流程图感受一下:
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/thirteen-12.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/control/thirteen-12.png)
用在 for 循环中的示例:
......
......@@ -16,13 +16,13 @@ Java 中的数据类型可分为 2 种:
来个思维导图,感受下。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/nine-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-grammar/nine-01.png)
通过[上一节](https://mp.weixin.qq.com/s/IgBpLGn0L1HZymgI4hWGVA)的学习,我们知道变量可以分为局部变量、成员变量、静态变量。
当变量是局部变量的时候,必须得先初始化,否则编译器不允许你使用它。拿 int 来举例吧,看下图。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/nine-02.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-grammar/nine-02.png)
当变量是成员变量或者静态变量时,可以不进行初始化,它们会有一个默认值,仍然以 int 为例,来看代码:
......@@ -80,7 +80,7 @@ public class LocalVar {
(终于知道 1024 和程序员的关系了吧?狗头保命)
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/nine-03.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-grammar/nine-03.png)
接下来,我们再来详细地了解一下 8 种基本数据类型。
......@@ -162,11 +162,11 @@ double d1 = 12.3
Tips:单精度是这样的格式,1 位符号,8 位指数,23 位小数,有效位数为 7 位。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/nine-04.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-grammar/nine-04.png)
双精度是这样的格式,1 位符号,11 位指数,52 为小数,有效位数为 16 位。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/nine-05.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-grammar/nine-05.png)
取值范围取决于指数位,计算精度取决于小数位(尾数)。小数位越多,则能表示的数越大,那么计算精度则越高。
......@@ -241,7 +241,7 @@ arrays 是一个 int 类型的数组,对吧?打印结果如下所示:
`[I` 表示数组是 int 类型的,@ 后面是十六进制的 hashCode——这样的打印结果太“人性化”了,一般人表示看不懂!为什么会这样显示呢?查看一下 `java.lang.Object` 类的 `toString()` 方法就明白了。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/nine-06.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-grammar/nine-06.png)
数组虽然没有显式定义成一个类,但它的确是一个对象,继承了祖先类 Object 的所有方法。那为什么数组不单独定义一个类来表示呢?就像字符串 String 类那样呢?
......@@ -287,7 +287,7 @@ public class ArrayList<E> extends AbstractList<E>
对于接口类型的引用变量来说,你没法直接 new 一个:
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/nine-07.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-grammar/nine-07.png)
只能 new 一个实现它的类的对象——那自然接口也是引用数据类型了。
......
......@@ -37,7 +37,7 @@
- 尽量不要省略成单词的首字母,但以下情形例外:DO/BO/DTO/VO/AO/ PO / UID 等
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/fifteen-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-grammar/fifteen-01.png)
另外,如果是抽象类的话,使用 Abstract 或 Base 开头;如果是异常类的话,使用 Exception 结尾;如果是测试类的话,使用 Test 结尾。
......
......@@ -4,7 +4,7 @@
“是的,三妹。运算符在 Java 中占据着重要的位置,对程序的执行有着很大的帮助。除了常见的加减乘除,还有许多其他类型的运算符,来看下面这张思维导图。”
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/eleven-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-grammar/eleven-01.png)
### 01、算数运算符
......@@ -111,7 +111,7 @@ System.out.println(y + " " + x);// 10 11
关系运算符用来比较两个操作数,返回结果为 true 或者 false。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/eleven-02.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-grammar/eleven-02.png)
来看示例:
......@@ -152,7 +152,7 @@ public class BitOperator {
PS:现代的二进制记数系统由戈特弗里德·威廉·莱布尼茨于 1679 年设计。莱布尼茨是德意志哲学家、数学家,历史上少见的通才。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/eleven-03.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-grammar/eleven-03.png)
来看示例:
......@@ -291,7 +291,7 @@ public class AssignmentOperator {
不过在进行数值的赋值时,需要小点心,比如说下面这种情况:
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/eleven-04.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-grammar/eleven-04.png)
编译器之所以提示错误,是因为 = 右侧的算术表达式默认为 int 类型,左侧是 short 类型的时候需要进行强转。
......
......@@ -66,7 +66,7 @@ List<Integer> list = new ArrayList<>();
“作为局部变量时,基本类型在栈中直接存储的具体数值,而包装类型则存储的是堆中的引用。”我一边说着,一边打开 `draw.io` 画起了图。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/object-class/box-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-points/box-01.png)
很显然,相比较于基本类型而言,包装类型需要占用更多的内存空间,不仅要存储对象,还要存储引用。假如没有基本类型的话,对于数值这类经常使用到的数据来说,每次都要通过 new 一个包装类型就显得非常笨重。
......
......@@ -104,7 +104,7 @@ writer2:Writer@b97c004{age=18, name='三妹'}
可以看得出,浅拷贝后,writer1 和 writer2 引用了不同的对象,但值是相同的,说明拷贝成功。之后,修改了 writer2 的 name 字段,直接上图就明白了。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/object-class/deep-copy-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-points/deep-copy-01.png)
之前的例子中,Writer 类只有两个字段,没有引用类型字段。那么,我们再来看另外一个例子,为 Writer 类增加一个自定义的引用类型字段 Book,先来看 Book 的定义。
......@@ -203,7 +203,7 @@ writer2:Writer@36d4b5c age=18, name='二哥', book=Book@32e6e9c3 bookName='永
与之前例子不同的是,writer2.book 变更后,writer1.book 也发生了改变。这是因为字符串 String 是不可变对象,一个新的值必须在字符串常量池中开辟一段新的内存空间,而自定义对象的内存地址并没有发生改变,只是对应的字段值发生了改变,见下图。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/object-class/deep-copy-02.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-points/deep-copy-02.png)
“哇,哥,果真一图胜千言,我明白了。”三妹似乎对我画的图很感兴趣呢,“那你继续说深拷贝吧!”
......@@ -304,7 +304,7 @@ writer2:Writer@6d00a15d age=18, name='二哥', book=Book@51efea79 bookName='
不只是 writer1 和 writer2 是不同的对象,它们中的 book 也是不同的对象。所以,改变了 writer2 中的 book 并不会影响到 writer1。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/object-class/deep-copy-03.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-points/deep-copy-03.png)
不过,通过 `clone()` 方法实现的深拷贝比较笨重,因为要将所有的引用类型都重写 `clone()` 方法,当嵌套的对象比较多的时候,就废了!
......
......@@ -20,7 +20,7 @@
话音刚落,我就在 IDEA 中噼里啪啦地敲了起来。两段代码,分别是方法重写和方法重载。然后,把这两段代码截图到 draw.io(一个很漂亮的在线画图网站)上,加了一些文字说明。最后,打开 Photoscape X,把两张图片合并到了一起。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/21-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-points/21-01.png)
### 02、方法重载
......@@ -94,7 +94,7 @@ class Adder {
“编译时报错优于运行时报错,所以当两个方法的名字相同,参数个数和类型也相同的时候,虽然返回值类型不同,但依然会提示方法已经被定义的错误。”
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/21-02.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-points/21-02.png)
“你想啊,三妹。我们在调用一个方法的时候,可以指定返回值类型,也可以不指定。当不指定的时候,直接指定 `add(1, 2)` 的时候,编译器就不知道该调用返回 int 的 `add()` 方法还是返回 double 的 `add()` 方法,产生了歧义。”
......@@ -132,7 +132,7 @@ String[] args
“由于可以通过改变参数类型的方式实现方法重载,那么当传递的参数没有找到匹配的方法时,就会发生隐式的类型转换。”
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/21-03.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-points/21-03.png)
“如上图所示,byte 可以向上转换为 short、int、long、float 和 double,short 可以向上转换为 int、long、float 和 double,char 可以向上转换为 int、long、float 和 double,依次类推。”
......@@ -207,7 +207,7 @@ public class OverloadingTypePromotion2 {
“二哥,我又想到一个问题。当有两个方法 `sum(long a, int b)``sum(int a, long b)`,参数个数相同,参数类型相同,只不过位置不同的时候,会发生什么呢?”
“当通过 `obj.sum(20, 20)` 来调用 sum 方法的时候,编译器会提示错误。”
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/21-04.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-points/21-04.png)
“不明确,编译器会很为难,究竟是把第一个 20 从 int 转成 long 呢,还是把第二个 20 从 int 转成 long,智障了!所以,不能写这样让编译器左右为难的代码。”
......
......@@ -33,7 +33,7 @@ age 是基本类型,值就保存在变量中,而 name 是引用类型,变
“画幅图。”
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/object-class/pass-by-value-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-points/pass-by-value-01.png)
当用 = 赋值运算符改变 age 和 name 的值时。
......@@ -46,7 +46,7 @@ name = "三妹";
对于引用类型 name,赋值运算符会改变对象引用中保存的地址,原来的地址被覆盖,但原来的对象不会被覆盖。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/object-class/pass-by-value-02.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-points/pass-by-value-02.png)
“三妹,注意听,接下来,我们来说说基本数据类型的参数传递。”
......@@ -115,11 +115,11 @@ class ReferenceTypeDemo {
在调用 `modify()` 方法的时候,形参 name1 复制了 name 的地址,指向的是堆中“二哥”的位置。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/object-class/pass-by-value-03.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-points/pass-by-value-03.png)
`modify()` 方法调用结束后,改变了形参 name1 的地址,但 `main()` 方法中 name 并没有发生改变。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/object-class/pass-by-value-04.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-points/pass-by-value-04.png)
总结:
......
......@@ -13,7 +13,7 @@ ASCII 码由电报码发展而来,第一版标准发布于 1963 年,最后
ASCII 码的局限在于只能显示 26 个基本拉丁字母、阿拉伯数字和英式标点符号,因此只能用于显示现代美国英语,对于其他一些语言则无能无力,比如在法语中,字母上方有注音符号,它就无法用 ASCII 码表示。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/ten-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-points/ten-01.png)
PS:拉丁字母(也称为罗马字母)是多数欧洲语言采用的字母系统,是世界上最通行的字母文字系统,是罗马文明的成果之一。
......@@ -21,15 +21,15 @@ PS:拉丁字母(也称为罗马字母)是多数欧洲语言采用的字母
在我们的印象中,可能说拉丁字母多少有些陌生,说英语字母可能就有直观的印象了。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/ten-02.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-points/ten-02.png)
PPS:阿拉伯数字,我们都很熟悉了。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/ten-03.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-points/ten-03.png)
但是,阿拉伯数字并非起源于阿拉伯,而是起源于古印度。学过历史的我们应该有一些印象,阿拉伯分布于西亚和北非,以阿拉伯语为主要语言,以伊斯兰教为主要信仰。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/ten-04.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-points/ten-04.png)
处在这样的地理位置,做起东亚和欧洲的一些生意就很有优势,于是阿拉伯数字就由阿拉伯人传到了欧洲,因此得名。
......@@ -39,7 +39,7 @@ PPPS:英式标点符号,也叫英文标点符号,和中文标点符号很
在很多人的印象中,古文是没有标点符号的,但管锡华博士研究指出,中国早在先秦时代就有标点符号了,后来融合了一些英文标点符号后,逐渐形成了现在的中文标点符号。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/ten-05.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-points/ten-05.png)
**2)Unicode**
......@@ -54,7 +54,7 @@ PS:常用字大概 2500 个,次常用字 1000 个。
要知道,世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/ten-06.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-points/ten-06.png)
PPS:这“锟斤拷”价格挺公道的啊!!!(逃
......@@ -64,7 +64,7 @@ PPS:这“锟斤拷”价格挺公道的啊!!!(逃
Unicode 至今仍在不断增修,每个新版本都会加入更多新的字符。目前最新的版本为 2020 年 3 月公布的 13.0,收录了 13 万个字符。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/ten-07.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-points/ten-07.png)
Unicode 是一个很大的集合,现在的规模可以容纳 100 多万个符号。每个符号的编码都不一样,比如,`U+0639`表示阿拉伯字母 `Ain``U+0041` 表示英语的大写字母 `A``U+4E25` 表示汉字`严`
......@@ -157,7 +157,7 @@ UTF-16 使用 2 个或者 4 个字节来存储字符。
这个 `𐐷` 字符很特殊,Unicode 编码是 `U+10437`,它就无法使用一个 char 来表示,当你尝试用 char 来表示时,它会被 IDEA 转成 UTF-16 十六进制字符代码 `\uD801\uDC37`(与此同时,编译器会提醒你最好把它声明成 String 类型)。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/ten-08.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/core-points/ten-08.png)
也就是说,在 Java 中,char 会占用两个字节,超出 char 的承受范围('\u0000'(0)和 '\uffff'(65,535))的字符,都将无法表示。
......
......@@ -70,7 +70,7 @@ checked 异常(检查型异常)在源代码里必须显式地捕获或者抛
“我先画一幅思维导图给你感受一下。”
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/exception/gailan-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/exception/gailan-01.png)
首先,Exception 和 Error 都继承了 Throwable 类。换句话说,只有 Throwable 类(或者子类)的对象才能使用 throw 关键字抛出,或者作为 catch 的参数类型。
......@@ -98,7 +98,7 @@ Class clz = Class.forName("com.itwanger.s41.Demo1");
如果没做处理,比如说在 Intellij IDEA 环境下,就会提示你这行代码可能会抛出 `java.lang.ClassNotFoundException`
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/exception/gailan-02.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/exception/gailan-02.png)
建议你要么使用 try-catch 进行捕获:
......
......@@ -41,7 +41,7 @@ Exception in thread "main" java.lang.ArithmeticException: 年纪未满 18 岁,
`Class.forName()` 方法在执行的时候可能会遇到 `java.lang.ClassNotFoundException` 异常,一个检查型异常,如果没有做处理,IDEA 就会提示你,要么在方法签名上声明,要么放在 try-catch 中。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/exception/throw-throws-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/exception/throw-throws-01.png)
“那什么情况下使用 throws 而不是 try-catch 呢?”三妹问。
......
......@@ -178,7 +178,7 @@ static int test2 () {
“三妹,来看一下源码的文档注释就全明白了!”
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/exception/try-catch-finally-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/exception/try-catch-finally-01.png)
至于参数 status 的值也很好理解,如果是异常退出,设置为非 0 即可,通常用 1 来表示;如果是想正常退出程序,用 0 表示即可。
......
......@@ -293,5 +293,5 @@ java.lang.Exception: out()
**教妹学 Java**》预计一个月左右会有一次内容更新和完善,大家在我的公众号 **沉默王二** 后台回复“**03**” 即可获取最新版!如果觉得内容不错的话,欢迎转发分享!
<img src="https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/itwanger.png" alt="图片没显示的话,可以微信搜索「沉默王二」关注" style="zoom:50%;" />
<img src="https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/itwanger.png" alt="图片没显示的话,可以微信搜索「沉默王二」关注" style="zoom:50%;" />
......@@ -163,18 +163,18 @@ public Object invoke(Object obj, Object... args)
`invoke()` 方法实际上是委派给 MethodAccessor 接口来完成的。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/object-class/fanshe-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/fanshe/fanshe-01.png)
MethodAccessor 接口有三个实现类,其中的 MethodAccessorImpl 是一个抽象类,另外两个具体的实现类继承了这个抽象类。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/object-class/fanshe-02.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/fanshe/fanshe-02.png)
- NativeMethodAccessorImpl:通过本地方法来实现反射调用;
- DelegatingMethodAccessorImpl:通过委派模式来实现反射调用;
通过 debug 的方式进入 `invoke()` 方法后,可以看到第一次反射调用会生成一个委派实现 DelegatingMethodAccessorImpl,它在生成的时候会传递一个本地实现 NativeMethodAccessorImpl。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/object-class/fanshe-03.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/fanshe/fanshe-03.png)
也就是说,`invoke()` 方法在执行的时候,会先调用 DelegatingMethodAccessorImpl,然后调用 NativeMethodAccessorImpl,最后再调用实际的方法。
......@@ -197,7 +197,7 @@ for (int i = 0;i < 20; i++) {
`invoke()` 方法处加断点进入 debug 模式,当 i = 15 的时候,也就是第 16 次执行的时候,会进入到 if 条件分支中,改变 DelegatingMethodAccessorImpl 的委派模式 delegate 为 `(MethodAccessorImpl)(new MethodAccessorGenerator()).generateMethod()`,而之前的委派模式 delegate 为 NativeMethodAccessorImpl。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/object-class/fanshe-04.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/fanshe/fanshe-04.png)
“这下明白了吧?三妹。”我说,“接下来,我们再来熟悉一下反射当中常用的 API。”
......
......@@ -22,7 +22,7 @@ final int age = 18;
“当尝试将 age 的值修改为 30 的时候,编译器就生气了。”
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/23-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/keywords/23-01.png)
“再来看这段代码。”
......@@ -50,7 +50,7 @@ final Pig pig = new Pig();
“如果尝试将 pig 重新赋值的话,编译器同样会生气。”
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/23-02.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/keywords/23-02.png)
“但我们仍然可以去修改 pig 对象的 name。”
......@@ -62,7 +62,7 @@ System.out.println(pig.getName()); // 特立独行
“另外,final 修饰的成员变量必须有一个默认值,否则编译器将会提醒没有初始化。”
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/23-03.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/keywords/23-03.png)
“final 和 static 一起修饰的成员变量叫做常量,常量名必须全部大写。”
......@@ -89,7 +89,7 @@ public class ArgFinalTest {
“如果尝试去修改它的话,编译器会提示以下错误。”
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/23-04.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/keywords/23-04.png)
### 02、final 方法
......@@ -116,7 +116,7 @@ public class Actor {
“当我们想要重写该方法的话,就会出现编译错误。”
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/23-05.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/keywords/23-05.png)
“如果一个类中的某些方法要被其他方法调用,则应考虑事被调用的方法称为 final 方法,否则,重写该方法会影响到调用方法的使用。”
......@@ -178,7 +178,7 @@ public final class Writer {
“尝试去继承它,编译器会提示以下错误,Writer 类是 final 的,无法继承。”
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/23-06.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/keywords/23-06.png)
“不过,类是 final 的,并不意味着该类的对象是不可变的。”
......
......@@ -54,7 +54,7 @@ public class Student {
“哦哦,别担心,三妹,画幅图你就全明白了。”说完我就打开 draw.io 这个网址,认真地画起了图。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/19-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/keywords/19-01.png)
“现在,是不是一下子就明白了?”看着这幅漂亮的手绘图,我心里有点小开心。
......@@ -83,7 +83,7 @@ public class Counter {
我在侃侃而谈,而三妹似乎有些不太明白。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/19-02.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/keywords/19-02.png)
“没关系,三妹,你先盲猜一下,这段代码输出的结果是什么?”
......@@ -135,7 +135,7 @@ public class StaticCounter {
“另外,需要注意的是,由于静态变量属于一个类,所以不要通过对象引用来访问,而应该直接通过类名来访问,否则编译器会发出警告。”
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/19-03.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/keywords/19-03.png)
### 02、 静态方法
......@@ -196,11 +196,11 @@ public class StaticMethodStudent {
“先是在静态方法中访问非静态变量,编译器不允许。”
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/19-04.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/keywords/19-04.png)
“然后在静态方法中访问非静态方法,编译器同样不允许。”
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/19-05.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/keywords/19-05.png)
“关于静态方法的使用,这下清楚了吧,三妹?”
......@@ -212,7 +212,7 @@ public class StaticMethodStudent {
“java.lang.Math 类的几乎所有方法都是静态的,可以直接通过类名来调用,不需要创建类的对象。”
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/19-06.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/keywords/19-06.png)
### 03、静态代码块
......@@ -266,7 +266,7 @@ public class StaticBlockNoMain {
“在命令行中执行 `java StaticBlockNoMain` 的时候,会抛出 NoClassDefFoundError 的错误。”
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/19-07.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/keywords/19-07.png)
“三妹,来看下面这个例子。”
......@@ -331,6 +331,6 @@ public class Singleton {
“三妹,你看,在 Singleton 类上加 static 后,编译器就提示错误了。”
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/19-08.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/keywords/19-08.png)
三妹点了点头,所有所思。
\ No newline at end of file
......@@ -211,7 +211,7 @@ hello
“不过,需要注意的是,`this()` 必须放在构造方法的第一行,否则就报错了。”
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/20-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/keywords/20-01.png)
### 05、作为参数在方法中传递
......
......@@ -71,7 +71,7 @@ public class Car {
说完这句话,我打开 draw.io,使上了吃奶的劲,画出了下面这幅图。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/22-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/object-class/22-01.png)
“哦,原来如此啊!”三妹仿佛发现了新大陆,意味深长地说。
......
......@@ -20,7 +20,7 @@ abstract class AbstractPlayer {
抽象类是不能实例化的,尝试通过 `new` 关键字实例化的话,编译器会报错,提示“类是抽象的,不能实例化”。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/object-class/abstract-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/object-class/abstract-01.png)
虽然抽象类不能实例化,但可以有子类。子类通过 `extends` 关键字来继承抽象类。就像下面这样。
......@@ -33,11 +33,11 @@ public class BasketballPlayer extends AbstractPlayer {
当我们尝试在一个普通类中定义抽象方法的时候,编译器会有两处错误提示。第一处在类级别上,提示“这个类必须通过 `abstract` 关键字定义”,见下图。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/object-class/abstract-02.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/object-class/abstract-02.png)
第二处在尝试定义 abstract 的方法上,提示“抽象方法所在的类不是抽象的”,见下图。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/object-class/abstract-03.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/object-class/abstract-03.png)
抽象类中既可以定义抽象方法,也可以定义普通方法,就像下面这样:
......@@ -64,7 +64,7 @@ public class BasketballPlayer extends AbstractPlayer {
如果没有实现的话,编译器会提示“子类必须实现抽象方法”,见下图。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/object-class/abstract-04.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/object-class/abstract-04.png)
“二哥,抽象方法我明白了,那什么时候使用抽象方法呢?能给我讲讲它的应用场景吗?”三妹及时的插话道。
......@@ -220,7 +220,7 @@ public class FileReaderTest {
在项目的 resource 目录下建一个文本文件,名字叫 helloworld.txt,里面的内容就是“Hello World”。文件的具体位置如下图所示,我用的集成开发环境是 Intellij IDEA。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/object-class/abstract-05.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/object-class/abstract-05.png)
在 resource 目录下的文件可以通过 `ClassLoader.getResource()` 的方式获取到 URI 路径,然后就可以取到文本内容了。
......
......@@ -93,7 +93,7 @@ public class Bike {
通常情况下,无参构造方法是可以缺省的,我们开发者并不需要显式的声明无参构造方法,把这项工作交给编译器更轻松一些。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/18-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/object-class/18-01.png)
“二哥,默认构造方法的目的是什么?它为什么是一个空的啊?”三妹疑惑地看着我,提出了这个尖锐的问题。
......@@ -209,7 +209,7 @@ public class OverloadingConstrutorPerson {
构造方法和方法之间的区别还是蛮多的,比如说下面这些:
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/18-02.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/object-class/18-02.png)
......
......@@ -2,14 +2,14 @@
“哥,我看你朋友圈说《教妹学 Java》专栏收到了第一笔赞赏呀,虽然只有一块钱,但我也替你感到开心。”三妹的脸上洋溢着自信的微笑,仿佛这钱是打给她的一样。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/object-class/interface-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/object-class/interface-01.png)
“是啊,早上起来的时候看到这条信息,还真的是挺开心的,虽然只有一块钱,但是开源的第一笔,也是我人生当中的第一笔,真的非常感谢这个读者,值得纪念的一天。”我自己也掩饰不住内心的激动。
“有了这份鼓励,我相信你更新下去的动力更足了!”三妹今天说的话真的是特别令人喜欢。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/object-class/interface-02.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/object-class/interface-02.png)
“是啊是啊,所以,今天要更新第 26 讲了——接口。”我接着说,“对于面向对象编程来说,抽象是一个极具魅力的特征。如果一个程序员的抽象思维很差,那他在编程中就会遇到很多困难,无法把业务变成具体的代码。在 Java 中,可以通过两种形式来达到抽象的目的,一种上一篇的主角——[抽象类](https://mp.weixin.qq.com/s/WSmGwdtlimIFVVDVKfvrWQ),另外一种就是今天的主角——接口。”
......@@ -85,7 +85,7 @@ Java 官方文档上有这样的声明:
4)接口中允许定义 `default` 方法也是从 Java 8 开始的,比如说上例中的 `printDescription()` 方法,它始终由一个代码块组成,为,实现该接口而不覆盖该方法的类提供默认实现。既然要提供默认实现,就要有方法体,换句话说,默认方法后面不能直接使用“;”号来结束——编译器会报错。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/object-class/interface-03.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/object-class/interface-03.png)
“为什么要在接口中定义默认方法呢?”三妹好奇地问到。
......@@ -102,7 +102,7 @@ Java 官方文档上有这样的声明:
1)接口不允许直接实例化,否则编译器会报错。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/object-class/interface-04.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/object-class/interface-04.png)
需要定义一个类去实现接口,见下例。
......@@ -137,11 +137,11 @@ Serializable 接口用来为序列化的具体实现提供一个标记,也就
3)不要在定义接口的时候使用 final 关键字,否则会报编译错误,因为接口就是为了让子类实现的,而 final 阻止了这种行为。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/object-class/interface-05.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/object-class/interface-05.png)
4)接口的抽象方法不能是 private、protected 或者 final,否则编译器都会报错。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/object-class/interface-06.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/object-class/interface-06.png)
5)接口的变量是隐式 `public static final`(常量),所以其值无法改变。
......@@ -196,7 +196,7 @@ Exception in thread "main" java.lang.CloneNotSupportedException: com.cmower.bael
如果有两个类共同继承(extends)一个父类,那么父类的方法就会被两个子类重写。然后,如果有一个新类同时继承了这两个子类,那么在调用重写方法的时候,编译器就不能识别要调用哪个类的方法了。这也正是著名的菱形问题,见下图。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/object-class/interface-07.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/object-class/interface-07.png)
简单解释下,ClassC 同时继承了 ClassA 和 ClassB,ClassC 的对象在调用 ClassA 和 ClassB 中重写的方法时,就不知道该调用 ClassA 的方法,还是 ClassB 的方法。
......
......@@ -17,7 +17,7 @@
方法的声明反映了方法的一些信息,比如说可见性、返回类型、方法名和参数。如下图所示。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/17-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/object-class/17-01.png)
**访问权限**:它指定了方法的可见性。Java 提供了四种访问权限修饰符:
......@@ -69,7 +69,7 @@ public class PredefinedMethodDemo {
我们可以通过集成开发工具查看预先定义方法的方法签名,当我们把鼠标停留在 `println()` 方法上面时,就会显示下图中的内容:
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/17-02.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/object-class/17-02.png)
`println()` 方法的访问权限修饰符是 public,返回类型为 void,方法名为 println,参数为 `String x`,以及 Javadoc(方法是干嘛的)。
......
......@@ -149,7 +149,7 @@ null
第二种:`main()` 方法不在 Person 类中,而在另外一个类中。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/16-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/object-class/16-01.png)
实际开发中,我们通常不在当前类中直接创建对象并使用它,而是放在使用对象的类中,比如说上图中的 PersonTest 类。
......@@ -213,7 +213,7 @@ public class Person {
person 被称为对象 Person 的引用变量,见下图:
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/16-02.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/object-class/16-02.png)
通过对象的引用变量,可以直接对字段进行初始化(`person.name = "沉默王二"`),所以以上代码输出结果如下所示:
......
......@@ -49,7 +49,7 @@ public class HelloWorld {
IDEA 会自动保存,在代码编辑面板中右键,在弹出的菜单中选择「Run 'HelloWorld.main()'」,如下图所示:
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/four-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/four-01.png)
等代码编译结束后,就可以在 Run 面板里看到下面的内容:
......
......@@ -10,7 +10,7 @@ Sun 公司为了抢占市场先机,在 1991 年成立了一个由詹姆斯·
**Oak** 是“Java”的第二个名字,这次就有点意义了。Oak(橡树)是力量的象征,被美国、法国、德国等许多欧美国家选为国树。橡树长下面这样。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/two-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/two-01.png)
1992 年,Oak 的雏形有了,但项目组在向硬件生产商进行商演的时候,并没有获得认可,于是 Oak 就被搁置一旁了。
......@@ -24,7 +24,7 @@ Sun 公司为了抢占市场先机,在 1991 年成立了一个由詹姆斯·
“Java”是印度尼西亚爪哇岛的英文名,因生产咖啡而闻名,所以,小伙伴也看到了,Java 这个单词经常和一杯冒着热气的咖啡一起出现。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/two-02.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/two-02.png)
同年,Sun 公司在 SunWorld 大会上正式发布了 Java 1.0 版本,第一次提出了“Write Once, Run anywhere”的口号。《时代》杂志将 Java 评为 1995 年十大最佳产品之一。
......
......@@ -4,7 +4,7 @@
“注释的种类确实不多,但还是挺有意思的,且听哥来给你说道说道。”
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/fourteen-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/fourteen-01.png)
......@@ -21,7 +21,7 @@ public void method() {
**但如果写在行尾的话,其实是不符合阿里巴巴的开发规约的**
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/fourteen-02.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/fourteen-02.png)
正确的单行注释如上图中所说,在被注释语句上方另起一行,使用 `//` 注释。
......@@ -86,24 +86,24 @@ PS:在 Intellij IDEA 中,按下 `/**` 后敲下回车键就可以自动添
**第一步**,在该类文件上右键,找到「Open in Terminal」 可以打开命令行窗口。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/fourteen-03.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/fourteen-03.png)
**第二步**,执行 javadoc 命令 `javadoc Demo.java -encoding utf-8``-encoding utf-8` 可以保证中文不发生乱码。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/fourteen-04.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/fourteen-04.png)
**第三步,**执行 `ls -l` 命令就可以看到生成代码文档时产生的文件,主要是一些可以组成网页的 html、js 和 css 文件。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/fourteen-05.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/fourteen-05.png)
**第四步**,执行 `open index.html` 命令可以通过默认的浏览器打开文档注释。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/fourteen-06.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/fourteen-06.png)
点击「Demo」,可以查看到该类更具体的注释文档。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/fourteen-07.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/fourteen-07.png)
### 04、文档注释的注意事项
......@@ -113,7 +113,7 @@ default 和 private 修饰的字段和方法的注释将会被忽略掉。因为
如果类不是 public 的话,javadoc 会执行失败。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/fourteen-08.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/fourteen-08.png)
2)文档注释中可以嵌入一些 HTML 标记,比如说段落标记 `<p>`,超链接标记 `<a></a>` 等等,但不要使用标题标记,比如说 `<h1>`,因为 javadoc 会插入自己的标题,容易发生冲突。
......@@ -125,7 +125,7 @@ default 和 private 修饰的字段和方法的注释将会被忽略掉。因为
比如说,在使用 String 类的时候,鼠标悬停在 String 上时可以得到以下提示。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/fourteen-09.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/fourteen-09.png)
2)所有的抽象方法(包括接口中的方法)必须要用Javadoc注释、除了返回值、参数、 异常说明外,还必须指出该方法做什么事情,实现什么功能。
......@@ -133,7 +133,7 @@ default 和 private 修饰的字段和方法的注释将会被忽略掉。因为
Intellij IDEA 中可以在「File and Code Templates」中设置。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/fourteen-10.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/fourteen-10.png)
语法如下所示:
......@@ -169,4 +169,4 @@ public class Test {
**教妹学 Java**》预计一个月左右会有一次内容更新和完善,大家在我的公众号 **沉默王二** 后台回复“**03**” 即可获取最新版!如果觉得内容不错的话,欢迎转发分享!
<img src="https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/itwanger.png" alt="图片没显示的话,可以微信搜索「沉默王二」关注" style="zoom:50%;" />
\ No newline at end of file
<img src="https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/itwanger.png" alt="图片没显示的话,可以微信搜索「沉默王二」关注" style="zoom:50%;" />
\ No newline at end of file
......@@ -10,15 +10,15 @@ JDK 是 Java Development Kit 的首字母缩写,是提供给 Java 程序员的
想要成为一名 Java 程序员,首先就需要在电脑上安装 JDK。当然了,新版的 Intellij IDEA(公认最好用的集成开发环境)已经支持直接下载 JDK 了。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/six-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/six-01.png)
并且支持下载不同版本的 JDK,除了 Oracle 的 OpenJDK,还有社区维护版 AdoptOpenJDK,里面包含了目前使用范围最广的 HotSpot 虚拟机。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/six-02.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/six-02.png)
如果下载比较慢的话,可以直接在 AdoptOpenJDK 官网上下载。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/six-03.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/six-03.png)
如果还是比较慢的话,通过 Oracle 官网下载吧!
......@@ -51,7 +51,7 @@ Java 程序运行的正式环境一般会选择 Linux 服务器,因为更安
可以看到有这么一些(只列出 Java 11 的部分——最近一个 LTS 版本):
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/six-04.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/six-04.png)
其中 JRE 为 java-11-openjdk.x86_64,JDK 为 java-11-openjdk-devel.x86_64。
......@@ -65,35 +65,35 @@ Java 程序运行的正式环境一般会选择 Linux 服务器,因为更安
如果出现以下结果,则表明安装成功:
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/six-05.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/six-05.png)
由于 JRE 中不包含 javac,所以 `javac -version` 的结果如下所示:
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/six-06.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/six-06.png)
那既然服务器上的 JRE 环境已经 OK 了,那我们就把之前的“Hello World”程序打成 jar 上传过去,让它跑起来。
第一步,Maven clean(对项目清理):
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/six-07.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/six-07.png)
第二步,Maven package(对项目打包):
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/six-08.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/six-08.png)
可以在 Run 面板中看到以下信息:
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/six-09.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/six-09.png)
说明项目打包成功了。
第三步,使用 FileZilla 工具将 jar 包上传到服务器指定目录。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/six-10.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/six-10.png)
第四步,使用 iTerm2 工具连接服务器。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/six-11.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/six-11.png)
第五步,执行以下命令:
......@@ -101,7 +101,7 @@ Java 程序运行的正式环境一般会选择 Linux 服务器,因为更安
可以看到以下结果:
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/six-12.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/six-12.png)
“搞定了,三妹,今天我们就学到这吧。”转动了一下僵硬的脖子后,我对三妹说,“开发环境需要安装 JDK,因为既需要编写源代码,还需要打包和测试;生产环境只需要安装 JRE,因为只需要运行编译打包好的 jar 包即可。”
......
......@@ -10,7 +10,7 @@
一开始,项目组打算使用 C++,但 C++ 无法达到跨平台的要求,比如在 Windows 系统下编译的 Hello.exe 无法直接拿到 Linux 环境下执行。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/seven-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/seven-01.png)
在当时,C++ 已经非常流行了,但无法跨平台,只能忍痛割爱了。
......@@ -18,7 +18,7 @@
三妹不知道有没有听过直译器(解释器)这玩意?(估计你没听过)就是每跑一行代码就生成机器码,然后执行,比如说 Python 和 Ruby 用的就是直译器。在每个操作系统上装一个直译器就好了,跨平台的目的就达到了。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/seven-02.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/seven-02.png)
但直译器有个缺点,就是没法像编译器那样对一些热点代码进行优化,从而让机器码跑得更快一些。
......@@ -26,7 +26,7 @@
来个结合体呗,编译器和直译器一块上!
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/seven-03.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/seven-03.png)
编译器负责把 Java 源代码编译成字节码(不清楚的小伙伴可以点击链接查看[上一节](https://mp.weixin.qq.com/s/GYDFndO0Q1Nqzcc_Te61gw)),Java 虚拟机(Java Virtual Machine,简称 JVM) 负责把字节码转换成机器码。转换的时候,可以做一些压缩或者优化,这样的机器码跑起来就快多了。
......@@ -42,7 +42,7 @@
说到这,三妹是不是想问,“都有哪些 Java 虚拟机呢?”来看下面这张思维导图:
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/seven-04.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/seven-04.png)
除了我们经常看到,经常听到的 Hotspot VM,还有很多,下面我来简单介绍一下。
......@@ -78,7 +78,7 @@ HotSpot 的技术优势就在于热点代码探测技术(名字就从这来)
关键是,1997 年 10 月,Sun 公司因为这事把微软告了,最后微软赔给了 Sun 公司 2000 万美金,并且终止了在 Java 虚拟机方面的发展。如果,我是说如果,如果微软保持着对 Java 的热情,后面还有 .Net 什么事?
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/seven-05.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/seven-05.png)
解释了这么多 Java 虚拟机后,三妹是不是想问,“Java 虚拟机长什么样子呢?”
......@@ -88,7 +88,7 @@ Java 虚拟机虽然是虚拟的,但它的内部是可以划分为:
- 运行时数据区(Runtime Data Areas)
- 执行引擎(Excution Engine)
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/seven-06.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/seven-06.png)
**1)类加载器**
......@@ -136,7 +136,7 @@ jdk.internal.loader.ClassLoaders$PlatformClassLoader@2d209079
来看下面这张图:
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/seven-07.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/seven-07.png)
- PC寄存器(PC Register),也叫程序计数器(Program Counter Register),是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的信号指示器。
......
......@@ -19,17 +19,17 @@ public class HelloWorld {
点击 IDEA 工具栏中的锤子按钮(Build Project,编译整个项目),如下图所示。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/five-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/five-01.png)
这时候,就可以在 src 的同级目录 target 下找到一个名为 HelloWorld.class 的文件。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/five-02.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/five-02.png)
如果找不到的话,在目录上右键选择「Reload from Disk,从磁盘上重新加载」,如下图所示:
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/five-03.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/five-03.png)
可以双击打开它。
......@@ -94,32 +94,32 @@ public class com/itwanger/five/HelloWorld {
那这个字节码文件是怎么看到的呢?可以通过 IDEA 菜单栏中的「View」→「Show Bytecode」查看,如下图所示。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/five-04.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/five-04.png)
PS:字节码并不是机器码,操作系统无法直接识别,需要在操作系统上安装不同版本的 Java 虚拟机(JVM)来识别。通常情况下,我们只需要安装不同版本的 JDK(Java Development Kit,Java 开发工具包)就行了,它里面包含了 JRE(Java Runtime Environment,Java 运行时环境),而 JRE 又包含了 JVM。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/five-05.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/five-05.png)
Windows、Linux、MacOS 等操作系统都有相应的 JDK,只要安装好了 JDK 就有了 Java 语言的运行时环境,就可以把一份字节码文件在不同的平台上运行了。可以在 [Oracle 官网](https://www.oracle.com/java/technologies/javase-jdk11-downloads.html)上下载不同版本的 JDK。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/five-06.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/five-06.png)
PPS:为什么要查看字节码呢?查看字节码文件更容易让我们搞懂 Java 代码背后的原理,比如搞懂 Java 中的各种语法糖的本质。
相比于 IDEA 自带的「Show Bytecode」功能,我更推荐 `jclasslib` 这款插件,可以在插件市场中安装(我已经安装过了)。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/five-07.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/five-07.png)
安装完成之后,点击 View -> Show Bytecode With jclasslib 即可通过 jclasslib 查看字节码文件了(点击之前,光标要停留在对应的类文件上),如下图所示。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/five-08.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/five-08.png)
使用 jclasslib 不仅可以直观地查看类对应的字节码文件,还可以查看类的基本信息、常量池、接口、字段、方法等信息,如下图所示。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/five-09.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/five-09.png)
也就是说,在编译阶段,Java 会将 Java 源代码文件编译为字节码文件。在这个阶段,编译器会进行一些检查工作,比如说,某个关键字是不是写错了,语法上是不是符合预期了,不能有很明显的错误,否则带到运行时再检查出来就会比较麻烦了。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/five-10.png)
\ No newline at end of file
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/five-10.png)
\ No newline at end of file
......@@ -16,7 +16,7 @@
Java 是一门计算机编程语言,高级、健壮、面向对象,并且非常安全。它由 Sun 公司在 1995 年开发,主力开发叫 James Gosling,被称为 Java 之父,就是下图这位,头秃的厉害。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/one-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/one-01.png)
“三妹啊,你要不要再考虑考虑?做程序员不容易啊”
......@@ -33,7 +33,7 @@ James Gosling 回忆说,“Java”是一个叫 Mark Opperman 的人提议的
使用十六进制编辑器打开由 Java 源代码编译出的二进制文件(.class 文件),就可以看得到,最前面的 8 个字符是 CA FE BA BE(定义文件类型的魔数),即词组“CAFE BABE”(咖啡屋宝贝)。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/one-02.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/one-02.png)
“二哥,能给我展示一段 Java 代码吗?我想感受一下。”
......
......@@ -2,7 +2,7 @@
尽管 Java 已经 25 岁了,但仍然“宝刀未老”。在 Stack Overflow 2019 年流行编程语言调查报告中,Java 位居第 5 位,有 41% 的受调开发者认为 Java 仍然是一门受欢迎的编程语言。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/three-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/three-01.png)
很多大型的互联网公司都在使用 Java,国内最有名的当属阿里巴巴,国外最有名的当属谷歌。那为什么 Java 如此流行呢?
......@@ -56,7 +56,7 @@ Java 在多线程方面做得非常突出,只要操作系统支持,Java 中
**物联网(IoT)领域:**
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/three-02.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/overview/three-02.png)
Oracle 表示,灵活性和流行度是 IoT 程序员选择 Java 的主要原因。Java 提供了大量的 API 库,可以很容易应用到嵌入式应用程序中。相比其他编程语言,比如 C 语言,Java 在切换平台时更加顺畅,不容易出错。
......
......@@ -58,11 +58,11 @@ String s1 = "三妹";
在 Java 8 之前,字符串常量池在永久代中。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/string/constant-pool-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/string/constant-pool-01.png)
Java 8 之后,移除了永久代,字符串常量池就移到了堆中。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/string/constant-pool-02.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/string/constant-pool-02.png)
“哥,能再简单给我解释一下方法区,永久代和元空间的概念吗?有点模糊。”三妹说。
......
......@@ -13,7 +13,7 @@
有一对双胞胎,姐姐叫阿丽塔,妹妹叫洛丽塔。我们普通人可能完全无法分辨谁是姐姐谁是妹妹,可她们的妈妈却可以轻而易举地辨认出。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/string/equals-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/string/equals-01.png)
`.equals()` 就好像我们普通人,看见阿丽塔以为是洛丽塔,看见洛丽塔以为是阿丽塔,看起来一样就觉得她们是同一个人;“==”操作符就好像她们的妈妈,要求更严格,观察更细致,一眼就能分辨出谁是姐姐谁是妹妹。
......
......@@ -60,7 +60,7 @@ false
“我来画幅图,帮助你理解下。”看到三妹惊讶的表情,我耐心地说。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/string/intern-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/string/intern-01.png)
“这下理解了吧?”我问三妹。
......@@ -92,7 +92,7 @@ true
“我再来画幅图,帮助你理解下。”
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/string/intern-02.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/string/intern-02.png)
“哇,我明白了!”三妹长舒一口气,大有感慨 intern 也没什么难理解的意味。
......
......@@ -87,7 +87,7 @@ cmower.split("[.]");
除此之外, 还可以使用 Pattern 类的 `quote()` 方法来包裹英文逗点“.”,该方法会返回一个使用 `\Q\E` 包裹的字符串。
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/string/split-01.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/string/split-01.png)
来看示例:
......@@ -178,7 +178,7 @@ String [] parts = cmower.split("(?=,)");
“它其实是正则表达式中的断言模式。”我说,“你有时间的话,可以看看前面我推荐的两份开源文档。”
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/string/split-02.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/string/split-02.png)
“`split()` 方法可以传递 2 个参数,第一个为分隔符,第二个为拆分的字符串个数。”我说。
......@@ -192,7 +192,7 @@ if (cmower.contains(",")) {
进入 debug 模式的话,可以看到以下内容:
![](https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/string/split-03.png)
![](https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/string/split-03.png)
也就是说,传递 2 个参数的时候,会直接调用 `substring()` 进行截取,第二个分隔符后的就不再拆分了。
......@@ -213,4 +213,4 @@ if (cmower.contains(",")) {
**教妹学 Java**》预计一个月左右会有一次内容更新和完善,大家在我的公众号 **沉默王二** 后台回复“**03**” 即可获取最新版!如果觉得内容不错的话,欢迎转发分享!
<img src="https://cdn.jsdelivr.net/gh/itwanger/Tech-Sister-Learn-Java/images/itwanger.png" alt="图片没显示的话,可以微信搜索「沉默王二」关注" style="zoom:50%;" />
\ No newline at end of file
<img src="https://cdn.jsdelivr.net/gh/itwanger/jmx-java/images/itwanger.png" alt="图片没显示的话,可以微信搜索「沉默王二」关注" style="zoom:50%;" />
\ No newline at end of file
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册