u02-基础语法

187 阅读13分钟

1. Java注释

概念: 注释就是对代码的一种文字说明,能提高程序的可读性,注释不参与代码的编译过程。

  • 注释原则:
    • 一眼就能看懂的代码是不需要注释的。
    • 注释中尽量不要出现废话。
  • 单行注释:
    • 格式: // 注释内容,建议在双正斜线和注释内容中间空一格。
    • 位置: 一般写在方法中,但不要写在代码行尾。
    • 场景: 当你的注释内容只有一行的时候使用。
    • 其他: 多个单行注释,可以当成是多行注释使用。
  • 多行注释:
    • 格式: /* 注释内容 */,注释内容前后建议均空一格。
    • 位置: 一般写在方法中。
    • 场景: 当你的注释内容有多行的时候使用。
    • 其他: 多行注释不能发生嵌套。
  • 文档注释:
    • 格式: /** 注释内容 */,注释内容前后建议均空一格。
    • 位置: 可以写在类上,方法上和属性上。
    • 其他: IDEA中的快捷键 ctrl + q 可以快速查看文档注释。

任何注释中都允许使用 TODO: 前缀来标识"暂留待写代码",在IDEA中可以使用 alt + 6 开打TODO视图,快速查看项目中所有暂留待写代码。

源码: /javase-start/

  • src: c.y.start.CommentDemo

/**
 * Documentation comments of class CommentDemo
 *
 * @author yap
 */
public class CommentDemo {

    /**
     * Documentation comments of methodA
     */
    public void method() {
        /*
         * Multi-line comments of method
         */
        // Single-line comment of method
        // TODO: Complement code here...
    }
}

1.1 文档化编程

概念: 我们应该推崇的文档化的编程,因为我们每个人都希望自己的产品能够配一套非常优秀详细的说明书,这个说明书的本质就是独立的文档,但这种文档维护麻烦,实时修改也很麻烦,所以Java的研发人员就做了如下三种优化:

  • 在开发中先使用虚拟的文档(文档注释),它和代码处于同一个.java文件中,改代码的同时,顺便就修改了文档。
  • 给文档注释设定了统一的格式,以保证所有人的文档都通用。
  • 允许使用javadoc.exe工具,提取出代码中的文档注释,并生成真正的文档。

文档注释就是可以跟代码写在一起,有着固定的格式,且能被javadoc工具提取成真实的HTML文档的一种特殊功能性注释。

1.2 文档注释格式

概念: 文档注释的常用注解:

  • @version:标识类的版本,如:@version 1.0
  • @author:标识类或方法的作者,如:@author JoeZhou
  • @deprecated:标识类或方法已过时,如:@deprecated As of JDK 1.8
  • @see:标识类或方法的参考的链接类,如:@see java.lang.Math
  • @date:标识类或方法的创建日期,如:@date 2020-05-20
  • @param:标识方法的参数,如:@param args 运行时指定的参数
  • @return:标识方法的返回值,如:@return 成功返回1,失败返回0
  • @throws :标识方法的异常,如:@throws Exception 除数不能为0
  • @exception:同 @throws,如:@exception Exception 除数不能为0

源码: /javase-start/

  • src: c.y.start.DocumentCommentDemo
/**
 * Documentation comments
 *
 * @author yap
 * @version 1.0
 * @date 2020-05-20
 */
public class DocumentCommentDemo {

    /**
     * Documentation comments
     *
     * @param numA the first num
     * @param numB the second num
     * @return the sum of two num
     * @see Math
     * @deprecated As of JDK version 1.8
     */
    public int sum(int numA, int numB) {
        return numA + numB;
    }
}

1.3 CMD提取文档注释

概念: 我们可以使用 javadoc.exe 工具将指定范围内的文档注释提取成HTML文档。

流程:

  • start/DocumentCommentDemo.java 复制到桌面上。
  • cmd: cd desktop 切换至桌面。
  • cmd: javadoc -encoding UTF-8 -d docs -version -author DocumentCommentDemo.java
    • -d docs:表示生成一个名字叫docs的文件夹,文档将在此生成。
    • -encoding UTF-8:表示以指定编码提取文档。
    • -version:可选,省略表示忽略类的版本号。
    • -author:可选,省略表示忽略类的作者。
  • 文档文件夹会默认生成在你的当前路径中。

1.4 IDEA提取文档注释

概念: 我们可以使用IDEA自带的功能将指定范围内的文档注释提取成HTML文档。

流程:

  • 点击 Tools > Generate JavaDoc... 进入到指定生成JavaDoc作用域界面。
  • 选择JavaDoc的生成范围:这里选择 Whole project
  • Output directory 一栏指定文档生成位置,这里建议多指定一层目录。
  • Other command line arguments 一栏,输入 -encoding UTF-8 来指定以何种编码来生成文档。
  • 点击 ok 完成文档生成。

2. 输出语句

概念: 输出语句也叫打印语句,负责将指定内容显示出来,默认显示在控制台。

  • 两大原则:
    • 输出语句一律不允许空输出。
    • 如果输出语句的参数是常量,直接输出,如果是变量,则输出的是变量中的值。
  • 换行输出:默认在最后输出一个换行符(\n),参数可以不写。
    • 格式: System.out.println(打印内容);
    • IDEA快捷生成:"sout" > tab
  • 不换行输出:没有换行的效果,参数必须写。
    • 格式:System.out.print(打印内容);
    • 没有对应的IDEA快捷生成方式。

源码: /javase-start/

  • src: c.y.start.PrintTest.print()
/**
 * @author yap
 */
public class PrintTest {

    @Test
    public void print() {

        // hot-key: "sout" > tab
        System.out.println("a");
        System.out.println("b");
        System.out.println("c");

        System.out.print(1);
        System.out.print(2);
        System.out.print(3);
    }

}

2.1 字符串拼接

概念:

  • + 两端均为数字,+ 视为数学中的加法运算符。
  • + 一端出现字符串,+ 视为字符串拼接运算符。

源码: /javase-start/

  • src: c.y.start.PrintTest.splicingString()
   @Test
    public void splicingString() {
        System.out.println("1" + 2 + 3 + "4" + "5");
    }

2.2 格式化输出语句

概念:

  • 格式: System.out.printf("字符串模板", 参数1, 参数2...);
    • %s:字符串占位符
    • %d:十进制整数占位符
    • %.2f:浮点数占位符:整数位保留个数.小数位保留个数
    • %o:八进制数占位符
    • %x:十六进制数占位符
  • 特点: 没有换行的效果,也同样不能空输出。
  • 其他: IDEA快捷生成方式:souf > tab

源码: /javase-start/

  • src: c.y.start.PrintTest.printf()
    @Test
    public void printf() {
        System.out.printf("%s, %d, %.2f", "a", 10, 12.5678);
    }

2.3 转义字符

概念:

  • 在java中,有一些字符串有自己独特的含义:
    • \n:换行符,相当于按了一下Enter键
    • \t:跳格符,相当于按了一下table键
    • \0:空格符,相当于按了一下space键
    • \uxxxx:unicode字符,输出16进制unicode字符
  • 在java中,转义字符就是一个反斜线 \,它能直接废除一些功能符的功能,使其变成一个纯文本:
    • \\n:输出 "\n"
    • \\t:输出 "\t"
    • \\0:输出 "\0"
    • \" :输出了一个双引号
    • \' :输出了一个单引号
    • \\ :输出了一个反斜线

链接: unicode工具网站

源码: /javase-start/

  • src: c.y.start.PrintTest.escapeCharacter()
    @Test
    public void escapeCharacter() {
        System.out.println("hello\nworld");
        System.out.println("hello\tworld");
        System.out.println("hello\0world");
        System.out.println("\u5468");

        System.out.println("hello\\nworld");
        System.out.println("hello\\tworld");
        System.out.println("hello\\0world");
        System.out.println("\\u5468");

        System.out.println("\"");
        System.out.println("\'");
        System.out.println("\\");
    }

2.4 错误输出语句

概念: 普通输出多用于单纯的文本的输出,错误输出常用于调试。

  • 格式:将 System.out 换成 System.err 即可。
  • IDEA快捷生成:"serr" > tab
  • 对比普通输出语句:
    • 普通输出语句能随意更改输出的位置,而错误输出语句只能输出在屏幕上。
    • 普通输出可能会被缓存,而错误输出语句没有缓存。
    • 错误输出在控制台中是红色的,更能引起我们的注意。
    • 错误输出语句可以被记录在我们的日志文件中,而普通的输出语句需要修改很多配置才能记录在日志文件中。

源码: /javase-start/

  • src: c.y.start.PrintTest.errorPrint()
    @Test
    public void errorPrint() {
        System.err.printf("printf: %s\n", "hello!");
        System.err.println("println: hello!");
        System.err.print("print: hello!\n");
    }

3. 变量

概念: 变量是在整个运行过程中,可以发生变化的量,这里强调的是一种能力,而不是一种结果。

3.1 变量的声明

概念: 声明一个变量的过程,就是在JVM内存中申请一块区域的过程:

  • 变量三要素:
    • 变量名: 变量的标识。
    • 变量类型: java是一门(必须)强(调)类型的语言,而且一旦这个类型确定好了,就不能变了。
    • 格式: 变量类型 变量名;
  • 相同类型的变量可以在同一行声明,用逗号隔开即可。
  • 变量在只声明未赋值的状态下,是不能使用(如输出、计算等操作)的。

源码: /javase-start/

  • src: c.y.start.VariableTest.declaration()
/**
 * @author yap
 */
public class VariableTest {

    @Test
    public void declaration() {
        int numA;
        int numB, numC;
    }
}

3.2 变量的赋值

概念: 赋值就是向变量申请的区域中存放值的过程:

  • java中使用 = 来完成赋值操作。
  • 声明和赋值可以在同一行,也可以不在同一行。
  • 赋值的时候要从后向前去理解。

源码: /javase-start/

  • src: c.y.start.VariableTest.assignment()
    @Test
    public void assignment() {
        int numA;
        int numB = 20, numC = 30;
        numA = 10;
        System.out.println(numA);
        System.out.println(numB);
        System.out.println(numC);
    }

3.3 变量名

概念:

  • 变量名硬性规定:
    • 变量名只能由数字、字母、下划线和$符号组成。
    • 数字不能开头。
    • 不能使用关键字: java系统自己用的、官方的、有着特殊功能和意义的词,如 publicstaticclass 等。
    • 不能使用保留字: java系统没有使用到,但是也不让我们使用的单词,如 constgoto 等。
  • 变量名软性规定:
    • 项目名:全小写,破折现风格,如:student-system、supermarket-project
    • 包的命名:全小写,域名倒置,如:com.baidu.test、com.google.controller
    • 类的命名:首字母大写驼峰制,一般使用名词,但不要复数形式,如:User、Person、Dog、Cat
    • 方法名:首字母小写驼峰制,一般使用动词,如:getName、setName
    • 变量名:首字母小写驼峰制,一般使用名词,如:name、age、gender
  • 只要像一个正常人一样去起名,就不会错!

无特殊情况,以我为主,有特殊情况,特殊对待。

1.3.1 代码沼泽

概念: 糟糕的代码带来的困境就是代码沼泽,花时间保持代码整洁不但有关效率,还有关生存。

  • 破窗理论: 环境中的不良现象如果被放任存在,会诱使人们仿效,甚至变本加厉。
    • 一幢有少许破窗的建筑为例,如果那些窗不被修理好,可能将会有破坏者破坏更多的窗户。最终他们甚至会闯入建筑内,如果发现无人居住,也许就在那里定居或者纵火。
    • 一面墙,如果出现一些涂鸦没有被清洗掉,很快的,墙上就布满了乱七八糟、不堪入目的东西。
    • 一条人行道有些许纸屑,不久后就会有更多垃圾,最终人们会视若理所当然地将垃圾顺手丢弃在地上。
    • 这个现象,就是犯罪心理学中的破窗效应。
  • 勒布朗詹姆斯曾经说过:稍后等于永不(Later equals never)。
  • 美国童子军军规:让营地比你来时更干净。

代码沼泽模拟图

image.png

1.3.2 代码整洁之道

概念:

  • 多费心,多修改: 命名的时候多花费点时间和精力,而且保持及时的更新,一旦发现有更好的名字,就换掉旧的。
  • 言到意到,见名知意: 如果你起的名字还得需要用到注释,来补充说明的话,那它就不怎么合格。
  • 别在乎变量名的长度: 变量名越长,描述的信息越多,但有趣的是,只要短名称足够清楚,就要比长名称好。
  • 明确才是王道:
    • 一定要避免误导性的名字,比如下面几种情况:
    • 别用 userList 来指定一组 user,不管这个变量是不是 List 类型的,改成 userGroup 或者 users 都会更好一些。
    • 别在变量名里面写出它的类型,nameString 并没有比 name 更有说服力。
    • 别在变量名中使用 IO,容易和数字 10 混淆。
  • 不做无意义的区分:
    • 比如有一个用户类叫 User,还有个类叫 Users,还有个类叫 UserInfo,还有个类叫 UserData,来你告诉我这四个类有什么区别呢?
    • variable 远不该出现在你变量名中,table 永远不应该出现在表名中。
    • 别在变量名上加前后缀,因为当我们阅读代码的速度变快的时候,前缀和后缀其实对于大脑来说,根本就看不见。
  • 使用能读出口的变量名:
    • private long timestamp;
    • private long yyyy_MM_dd_hh_mm_ss;

源码:

int m = 1000;// 不满足见名知意
int money = 1000;// 这是谁的钱的?你的还是我的?
int userMoney = 1000;// 用户的什么钱?工资?奖金?
int userSalary = 1000;// 基本工资?绩效工资?
int userBaseSalary = 1000;// 清晰明了!

4. 常量

概念: 在整个运行期间都无法发生改变的量,就叫常量。

  • 先天常量: 天生就没有改变的能力,如 123"123""abc",这些叫做常值常量或者面值常量。
  • 后天常量: 对某个变量添加了 final 修饰之后,这个变量就再也无法发生改变,也就变成了常量。

源码: /javase-start/

  • src: c.y.start.ConstantTest.constant()
/**
 * @author yap
 */
public class ConstantTest {

    @Test
    public void constant() {
        System.out.println(100);
        System.out.println("hello");
        final int num = 200;
        // num = 500;
        System.out.println(num);
    }

}

4.1 科学计数法

概念:

  • Java中的科学计数法以 e 或者 E 来表示,1.23e12 就代表1.23乘以10的12次方。
  • 建议使用大写的 E,建议 E 之前的部分的整数只使用一位。

源码: /javase-start/

  • src: c.y.start.ConstantTest.scientificNotation()

    @Test
    public void scientificNotation() {
        System.out.println(1.23e5);
        System.out.println(1.23E5);
        System.out.println(12.3E4);
        System.out.println(0.123E6);
    }

4.2 二进制数

概念: 在计算机中有四个常用概念:

  • 原码:
    • 一个数字在计算机中的二进制表达形式,也叫机器数
    • 原码中的最高位是符号位,0位正,1为负
    • 如:4的原码为:0000 0100
    • 如:-4的原码为:1000 0100
  • 真值:
    • 原码对应的真正的值(以10进制为例)叫真值
    • 如:0000 0100的真值为:4
    • 如:1000 0100的真值为:-4
  • 反码:
    • 对正数来说,反码就是原码
    • 对负数来说,反码是原码按位取反(符号位不变)之后的结果
    • 如:0000 0100的反码为:本身
    • 如:1000 0100的反码为:1111 1011
  • 补码:
    • 对正数来说,补码就是原码
    • 对负数来说,补码是它的反码+1的结果(符号位不参与计算进位,直接忽略)
    • 如:0000 0100的补码为:本身
    • 如:1000 0100的补码为:1111 1011 + 1 = 1111 1100
    • 补码的补码就是原码
    • java中使用 Integer.toBinaryString() 来查看一个数补码。

由于数据在计算机中的表示,最终以二进制的形式存在,所以有时候使用二进制,可以更有效率地解决问题。但二进制数太长了。比如100,用int类型的二进制数表达将是:0000 0000 0000 0000 0110 0100,面对这么长的数进行思考或操作,没有人会喜欢,因此C语言、C++以及java中,均没有提供在代码直接写二进制数的方法。

源码: /javase-start/

  • src: c.y.start.ConstantTest.toBinaryString()
    @Test
    public void toBinaryString() {
        System.out.println(Integer.toBinaryString(4));
        System.out.println(Integer.toBinaryString(-4));
    }

4.3 八进制数

概念:

  • 如果一个数是876,我们可以断定它不是八进制数,因为八进制数中不可能出7以上的数字。
  • 如果一个数是123,那么它是八进制数还是10进制数,都有可能。
  • 所以规定,一个数如果要指明它采用八进制,必须在它前面加上一个0,以免混淆。如:123 是十进制,但 0123 则表示采用八进制。

源码: /javase-start/

  • src: c.y.start.ConstantTest.octalNumber()
    @Test
    public void octalNumber() {
        System.out.println(0123);
        System.out.println(-0123);
    }

4.4 十六进制数

概念:

  • 如果不使用特殊的书写形式,16进制数也会和10进制相混。随便一个数:9876,就看不出它是16进制或10进制。16进制数必须以 0x 或者 0X 开头。
  • 0x15 表示一个16进制数,而 15 则表示一个十进制。
  • 十六进制只能用在无符号的正整数,如 -0xF2 ,编译器并不把它当成负数。

源码: /javase-start/

  • src: c.y.start.ConstantTest.hexadecimalNumber()
    @Test
    public void hexadecimalNumber() {
        System.out.println(0x123);
        System.out.println(-0x123);
        System.out.println(0X123);
        System.out.println(-0X123);
    }