入门篇-其之二-Java基础知识
阅读原文时间:2023年09月07日阅读:1

目录

对第一个Java程序的思考

前面我们已经写过一个使用Java语言输出四行诗句的代码:

public class Huanghelou {
    public static void main(String[] args) {
        System.out.println("昔人已乘黄鹤去,此地空余黄鹤楼。");
        System.out.println("黄鹤一去不复返,白云千载空悠悠。");
        System.out.println("晴川历历汉阳树,芳草萋萋鹦鹉洲。");
        System.out.println("日暮乡关何处是?烟波江上使人愁。");
    }
}

观察这段代码的结构,它的外层是由publicclass、文件名称(即Huanghelou)和一对大括号组成。

public class Huanghelou {

}

publicclass是Java内置的关键字(本文后面会讲到关键字),也就是说,这两个关键字是Java语言本身就规定的,小白在写代码的时候不能随意更改(例如:将public写成Publicclass一不小心写成了cLass等都是错误写法)。

class本意是“类”,class后面的标识符Huanghelou是当前这个类的名称,也就是说,这个类的类名是Huanghelou

public是权限修饰符(后续文章会讲到这个关键字的具体使用,这里小白有一个印象就可以了)。

一个Java文件至多只能有一个由public修饰的类,并且这个类的类名必须和Java文件名保持一致。

由上述规定我们可以推断出:不由public修饰的类不必和当前java文件名保持一致。这里我创建一个名为MyThirdProgram的Java文件,其内部代码如下:

class Dog {

}

执行了javac命令时,我们发现它并没有生成MyThirdProgram.class文件,而是生成了Dog.class文件。这是因为前面我们的MyThirdProgram.java文件中只有一个Dog类,并不包含由public修饰的MyThirdProgram类。

当然,我们的代码中既可以由public修饰的类和不由public修饰的类共存。这里我创建一个名为MyFourthProgram的Java文件,其内部代码如下:

public class MyFourthProgram {

}

class Cat {

}

class Sheep {

}

class Duck {

}

我们使用java命令进行编译,此时就会出现MyFourthProgramCatSheepDuck四个.class文件:

由此可以说明,一个Java文件中,如果有多个类,那么对这个Java文件执行编译命令时,就会生成多个相对应的字节码文件。

MySecondProgram类的内部,包含一个这样的结构:

public static void main(String[] args) {

}

前三个publicstaticvoid是Java的关键字(固定写法)。这个结构在Java中称作方法,这个方法称作main方法(因为方法名叫做main方法),main方法是Java程序的入口,也就是说,程序在运行时,会先执行main方法。

main方法必须定义成public static void main(String[] args) {...}的结构,这是Java的规范。

这段代码中,按行输出的语句是System.out.println();。也就是说,Java在执行这条语句的时候,会向控制台输出内容并换行。

当然,我们也可以选择不换行输出,System.out.print();语句就能保证输出的内容不换行。以下是示例代码:

public class PrintWithoutLine {
    public static void main(String[] args) {
        System.out.print("昔人已乘黄鹤去,此地空余黄鹤楼。");
        System.out.print("黄鹤一去不复返,白云千载空悠悠。");
        System.out.print("晴川历历汉阳树,芳草萋萋鹦鹉洲。");
        System.out.print("日暮乡关何处是?烟波江上使人愁。");
    }
}

以下是使用javac encoding PrintWithoutLine.javajava PrintWithoutLine命令的执行结果:

注释

注释是用来向代码中添加解释和说明,编写注释可以让我们更好地阅读和理解代码。在代码上写注释是一个好习惯,今天我写了50行的代码,但是过了三个月以后,如果我再看这段代码,会有种不知所措的感觉:这代码是我写的吗?它要实现的功能是什么?如果在编写代码以后写了注释,以后在阅读代码的时候这种窘境会大大减少,提高我们对代码的理解。

注释不会影响程序的运行,Java编译器会将注释忽略。

在Java编程语言中,有三种类型的注释:单行注释多行注释文档注释

单行注释,顾名思义,就是只能在某一行上写注释,使用两个斜杠//表示,格式为:// 单行注释内容

以前面写过的代码为例,如果我想在输出语句上方中添加一句注释:

// 输出一行内容
System.out.println("晴川历历汉阳树,芳草萋萋鹦鹉洲。");

当然,你也可以在这个输出语句后面所在行写注释:

System.out.println("晴川历历汉阳树,芳草萋萋鹦鹉洲。");        // 输出一行内容

扩展:《阿里巴巴Java开发手册》对单行注释内容的说明

1. 【强制】方法内部的单行注释,在被注释的语句上方另起一行,使用//注释。

也就是说,在我们日常开发的时候,编写注释时,推荐使用上述第一种注释风格。

2. 【强制】注释的双斜线与注释内容之间有且仅有一个空格。

正例:

3. 【推荐】与其“半吊子”英文来注释,不如用中文注释把问题说清楚。专有名词与关键字保持英文原文即可。

反例:“TCP 连接超时”解释成“传输控制协议连接超时”,理解反而费脑筋。

多行注释使用/* */进行表示,在/**/之间你可以写多行注释。

/*
    这是一段多行注释
    println()方法用于换行输出
    print()方法用与不换行输出
*/
System.out.println("黄鹤一去不复返,白云千载空悠悠。");
System.out.print("晴川历历汉阳树,芳草萋萋鹦鹉洲。");

多行注释之间不要使用嵌套。

/*/*这是一段多行注释,这样嵌套多行注释的方式是错误的*/*/
System.out.println("黄鹤一去不复返,白云千载空悠悠。");

这样嵌套是错误的。以上述代码为例,Java编译器认为多行注释最开头的是/*,能和它配对的是最近的*/,也就是说,这段多行注释的内容是:/*这是一段多行注释,这样嵌套多行注释的方式是错误的。最外层的*/无法识别为多行注释符号而导致编译错误。

文档注释是Java特有的一种注释,它用于对类、方法、变量等进行说明。

文档注释使用/**作为开头,*/作为结尾。

/**
 * 这个类中由一个main方法组成
 * 这个类的主要作用是通过控制台输出两句话
 *
 * @author iCode504
 * @version 1.0
 */
public class MyJavaDoc {
    /**
     * main方法用于输出两行诗句
     */
    public static void main(String[] args) {
        System.out.println("杨花落尽子规啼,闻道龙标过五溪。");
        System.out.println("我寄愁心与明月,随君直到夜郎西。");
    }
}

文档注释常用标签

在这段代码中,我们发现类上有一些特殊标签,它们以@作为开头,后面跟随一个指定的名字,例如:@author@version等。

@author用于指明当前代码的作者或所属组织,如果有多个作者可以加多个此标签,适用于类、接口等。例如:

/**
 * @author iCode504
 * @author Zhangsan
 * @author Lisi
 */

@version用于指明当前代码的版本号,适用于类、接口等。例如:

/**
 * @version 1.1.0
 */

@return标签作用于方法的文档注释上,表明当前方法的返回值类型。例如:

/**
 * main方法用于输出两行诗句
 * @return 不返回任何内容,因为返回值类型为void
 */
public static void main(String[] args) {
    System.out.println("杨花落尽子规啼,闻道龙标过五溪。");
    System.out.println("我寄愁心与明月,随君直到夜郎西。");
}

@param标签用于描述方法的参数信息。以main方法为例,它的参数是字符串数组类型的。

/**
 * main方法用于输出两行诗句
 * @param args是main方法的参数,类型为字符串数组类型
 */
public static void main(String[] args) {
    System.out.println("杨花落尽子规啼,闻道龙标过五溪。");
    System.out.println("我寄愁心与明月,随君直到夜郎西。");
}

@throws@exception标签用于描述方法可能会抛出的异常,例如:

/**
 * main方法用于输出两行诗句
 * @param args是main方法的参数,类型为字符串数组类型
 * @throws IOException 可能会抛出文件IO异常
 */
public static void main(String[] args) throws IOException {
    System.out.println("杨花落尽子规啼,闻道龙标过五溪。");
    System.out.println("我寄愁心与明月,随君直到夜郎西。");
}

使用javadoc命令生成网页风格的文档

我们可以使用javadoc命令对代码中的文档注释进行解析,生成一套网页形式的文档。命令格式为:

javadoc -d 文件路径 -encoding UTF-8 --label1 -label2 文件名.java

这里的label1label2是指文档注释中由@开头的标签,如果执行命令中写了那个标签,就会在网页中显示。当然,你的java文件中写了多少个不同类型的标签,你就可以在命令中写多少个--标签

以上述内容为例,如果我想输出所有文档注释和标签到网页,可以执行如下命令:

此时我们进入G:\Code\MyWorkspace\day02\MyFirstDoc路径中,我们可以看到如下内容,直接使用浏览器打开index.html

此时我们就能在网页中更加直观地看到我们写的文档注释内容了:

阿里巴巴Java开发手册关于文档注释的规范

1. 【强制】类、类属性、类方法的注释必须使用 Javadoc 规范,使用/**内容*/格式,不得使用// xxx方式。

说明:在 IDE 编辑窗口中,Javadoc 方式会提示相关注释,生成 Javadoc 可以正确输出相应注释;在 IDE中,工程调用方法时,不进入方法即可悬浮提示方法、参数、返回值的意义,提高阅读效率。

2. 【强制】所有的类都必须添加创建者和创建日期。

说明:在设置模板时,注意 IDEA 的@author 为${USER},而 eclipse 的@author 为`${user}`,大小写有区别,而日期的设置统一为 yyyy/MM/dd 的格式。

正例:

/**
 * @author iCode504
 * @date 2023/08/31
 */

3. 【推荐】代码修改的同时,注释也要进行相应的修改,尤其是参数、返回值、异常、核心逻辑等的修改。

说明:代码与注释更新不同步,就像路网与导航软件更新不同步一样,如果导航软件严重滞后,就失去了导航的意义。

关键字

Java关键字是由Java语言预先定义的保留的标识符,关键字不能用作变量名、方法名、类名等。这些关键字在Java语言中具有特殊的含义和用途,以下是Java常见的关键字(不需要记忆,因为这些关键字的用法会在后续文章中陆续讲到):

  • 数据类型相关的关键字:byteshortcharintlongfloatdoublebooleanvoid
  • 流程控制相关的关键字:ifelseswitchcasedefaultforwhiledobreakcontinuereturn
  • 权限控制关键字:publicprotectedprivate
  • 类和对象相关关键字:classnewextendsinterfaceimplementsthissuperinstanceofstaticabstractfinalenum
  • 异常处理关键字:trycatchfinallythrowthrowsassert
  • 包相关的关键字:importpackage
  • 多线程及同步相关的关键字:synchronizedvolatile
  • 序列化相关的关键字:transient
  • 保留字:gotoconst
  • 其他关键字:nativevar(JDK 10新增关键字)、null(不推荐做变量名)、strictfp

所有关键字的名称全部是小写,不是小写的一定不是关键字

标识符

Java中类名、方法名、变量名(关于变量名会在后面讲到)都称作标识符。以前面的代码为例:

public class MyJavaDoc {
    public static void main(String[] args) {
        System.out.println("");
        System.out.println("");
    }
}

这个类的类名叫做MyJavaDoc,方法名称作main

关于Java标识符,需要遵守如下规范(必须遵守,否则无法通过编译):

1. 标识符由大小写英文字母、数字、美元符号$、下划线组成。例如:ABC_MyProgram$Sheep都是正确写法;-SheepABC+等都是非法的。

2. 关键字不能作为标识符。例如:static关键字不可以做类名和方法名。

3. Java对标识符大小写是敏感的。例如:sheepCountSheepCount就是两个不同的标识符。

4. 数字不能作为标识符的开头,例如:标识符4Sheep就是错误写法。

扩展:《阿里巴巴Java开发手册》对标识符相关内容做出如下规范:

1. 【强制】代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束。

反例:_name / __name / $name / name_ / name$ / name__

2. 【强制】所有编程相关的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式。

说明:正确的英文拼写和语法可以让阅读者易于理解,避免歧义。注意,纯拼音命名方式更要避免采用。

正例:ali / alibaba / taobao / cainiao / aliyun/ youku / hangzhou等国际通用的名称,可视同英文。

反例:DaZhePromotion [打折] / getPingfenByName() [评分] / int 某变量 = 3

3. 【强制】类名使用 UpperCamelCase 风格(大驼峰命名方式,每个单词首字母大写),但以下情形例外:DO / BO / DTO / VO / AO / PO / UID 等。

正例:ForceCode / UserDO / HtmlDTO / XmlService / TcpUdpDeal / TaPromotion

反例:forcecode / UserDo / HTMLDto / XMLService / TCPUDPDeal / TAPromotion

4. 【强制】方法名、参数名、成员变量、局部变量都统一使用 lowerCamelCase(除了第一个单词首字母小写以外,其他单词首字母大写)风格。

正例:localValue / getHttpMessage() / inputUserId

5. 【强制】杜绝完全不规范的缩写,避免望文不知义。

反例:AbstractClass“缩写”命名成 AbsClass;condition“缩写”命名成 condi,此类随意缩写严重降低了代码的可阅读性。

变量

在Java编程语言中,变量是一种存储数据的“容器”,它们能存储各种类型的数据,例如:整数、浮点数、字符、布尔类型等。

变量是内存中的一个存储区域,正如其名:变量,变量存储的数据是可以变化的。

变量三要素:数据类型变量名变量值。在内存中的关系图如下:

变量主要用于在内存中存储数据。

创建Java变量的一般语法是:数据类型 变量名 = 变量值

  • 变量名可以自定义,但是需要遵守标识符命名规范。
  • 数据类型分为基础数据类型和引用数据类型,这里举例使用整数类型int,更多关于数据类型的内容详见下一篇文章。

这里以存储整数类型的int来举例:变量number的值为22,那么可以定义成:

int number = 22;

当然我们也可以先定义变量number,在对变量进行赋值。

int number;
number = 22;

以下是变量在代码中的使用案例:

public class MyVariable {
    public static void main(String[] args) {
        // 变量的定义和赋值都在同一行
        int age = 20;
        System.out.println(age);

        // 先定义变量,再为变量进行赋值
        int number;
        number = 22;
        System.out.println(number);

        // 变量是可以变化的:给number再次赋值为24,这个值会将原有的22进行覆盖
        number = 24;
        System.out.println(number);
    }
}

运行结果:

1. 变量必须先声明,后使用。凭空出现的变量是无法通过编译的。以下是错误写法:

public static void main(String[] args) {
    number = 1;        // 编译不通过,因为number并没有被声明
}

2. 使用变量名来访问这块区域的内存数据。以上述MyVariable类为例,当我们输出结果的时候,并没有直接使用变量值2022进行输出,而是使用变量名agenumber进行输出,因为通过变量名可以访问到这块区域的内存,存储的值是多少。

3. 变量的作用域:作用域在最近的外层大括号内,变量只有定义在作用域内才有效。以上述MyVariable类为例,变量agenumber的作用域只能在main方法中,因为两个变量最近的外层大括号就是在main方法的范围,出了main方法会导致Java将无法识别这个变量而出现编译错误。

4. 同一个作用域内,不能定义重名的变量。下面代码是错误写法:

public static void main(String[] args) {
    int number = 23;
    int number = 29;    // 错误写法,因为作用域内只能定义一个名为number的变量
}