Files
Java-Book/02:Java语言基础/01.md
T

226 lines
11 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Java基础(第二章)
## 1. 如何打印输出
**这一章中,我们使用面向过程(C语言的方式)来了解Java的基本语法。虽然说是和面向对象无关,但是我们需要一个函数入口(main)函数,这个函数上一章讲过,有固定的格式,且这个函数必须定义在一个Public类中。**
### 1.1. ComputeArea.java
先来看下面这个例子:
ComputeArea.java
```java
public class ComputeArea {
public static void main(String[] args) {
double radius = 0.0; // Declare radius
double area; // Declare area
// Assign a radius
radius = 20.0; // New value is radius
// Compute area
area = radius * radius * 3.14159;
// Display results
System.out.println("The area for the circle of radius " + radius + " is " + area);
}
}
```
2-10行的语法结构和C完全一致,这里我门只关心13行的代码。从第13行代码看出什么?首先是 System.out.println 这显然是一个函数,表示要打印一个字符串。
**按住ctl键盘,然后鼠标左键点击第13行的println,Eclipse会打开一个新的文件(PrintStream.class),并定位到println这个函数的位置。Eclipse这种特性叫做代码跳转,可以方便的浏览代码。**
在PrintStream.class 最顶部,发现这个文件的包是 java.io。想一想这个包为什么不是System.out?你可以继续点中out来参看源代码,发现out的定义是null。Java缺省初始化out是一个PrintStream对象,关于这一点超出了我们需要讨论的范围,大家只需要记住 System.out.println 类似C的println函数就可以了。System 是Java虚拟机的自带的一个包(类似C的标准库),也叫做API。
**注意这个文件是PrintStream.class,是编译后的binarycode,照理说应该看不到源代码的。主流的IDE可以根据Java的API自动查找源代码,便于我们的开发。**
尝试在代码中输入System.out.prin Eclipse会提示很多函数,界面如下:
![](img/20230303153149.png)
我们发现有很多print函数,函数名是一样的,但是参数不一样。这种方式是可行的,叫做函数重载,这种情况下,根据输入参数的类型或者是数量来匹配同名函数的一个确定版本。后面会专门讲到函数重载的技术。
另外我们还注意到有一个叫做printf的函数,这个函数和C的printf函数是一样的。
当你选择一个函数,右边会出现这个函数的英文解释。
**在Java中的字符串是用双引号来标识的,这点和C区别非常大;C语言的字符串是一个数组,Java是一种特定的数据类型(类、对象)。关于字符串,后面会详细讲解。这里只需要掌握字符串的表示(双引号),字符串的连接(+运算符)就可以了。**
再总结一下我们学的的:
1. main函数的固定写法;
2. main函数必须在一个public类中定义;
3. 字符串的表示和连接;
4. 如何使用打印函数。
### 1.2. 问题
1. main函数前面的static是什么意思?
2. main函数的参数 String\[\] args 是什么意思?
后面回讲到上述两个问题,你可以先研究一下。
## 2. 如何读取键盘输入
上面讲到了输出打印,现在来看看如何读取输入。在学习Java如何读取输入之前,我们回忆以下C是如何读取输入的?
C使用scanf函数配合一套字符串规则实现各种数据类型的输入和打印;Java的输入会更直观,接下来我们看一个简单的例子:
### 2.1. ComputeAreaWithConsoleInput.java
```java
import java.util.Scanner; // Scanner is in the java.util package
public class ComputeAreaWithConsoleInput {
public static void main(String[] args) {
// Create a Scanner object
Scanner input = new Scanner(System.in);
// Prompt the user to enter a radius
System.out.print("Enter a number for radius: ");
double radius = input.nextDouble();
// Compute area
double area = radius * radius * 3.14159;
// Display result
System.out.println("The area for the circle of radius " +
radius + " is " + area);
}
}
```
注意第一行的 import ..... 这个语句,这是把Scanner所在的包引入进来,相当于C的include语句。如果不写第一行,Eclipse会在地6行的 Scanner位置错误(红色下划线),这是只需要把鼠标移动到 Scanner 上面,会出现quike fix 的建议,如下图。这时只需要点击:Import 'Scanner' (java.util) 就可以了,Eclipse会自动加上import语句。
![](img/20230303153514.png)
这个例子稍微复杂一些,要读取键盘输入,这里主要使用的是Scanner类。类是一种抽象定义,例如我们前一章定义的圆,只需要说明圆有什么属性、有什么函数;但是并没有对其具体的属性进行赋值;也就是说圆这个类是所有圆对象(实体)的抽象描述。当对类进行实例化(使用 new 关键字),对其分配内存空间和对相应的属性进行初始化后,就得到了圆的对象(实体)。这点有点像C中的结构体指针,如果要生成一个可以操作的结构体,需要使用malloc函数分配结构体指针变量地址一样;同样 new关键字对应malloc函数。
因此第6行的Scanner是一个类,使用 new 关键字生成一个对象并把引用地址(指针)赋值给 input 这个变量。
**注意:Scanner即是一个类型,也是一个函数;不过这个函数必须和 new 关键字配合使用,这个函数叫做构造函数,当一个类实例化的时候用作进行一些初始化操作;构造函数是可以带参数的;例如这里的System.in。关于构造函数,后面有专门的内容进行讨论,这里只需要进行初步的了解。**
为Scanner类的构造函数传递一个叫做 System.in 的参数,表示Scanner从系统标准输入(一般是键盘)中读取数据。类似C的输入/输出重定向一样,Java也可以从文件读取数据,这个以后再讲。
当生成类型为Scanner的对象input后,就可以直接在input上使用相应的函数读取不同类型的数据了。例如nextDouble()函数是从键盘读取一个double类型的值,直到遇到空格或者是回车(空格并不能使nextDouble函数返回,只有回车可以让nextDouble函数返回)。程序在运行到nextDouble这个函数的时候,会等待,直到输入回车后把值读取到radius变量。
其他代码比较简单,就不解释了。
如果需要读取整数,字符串等其他类型的值如何办?看看input这个对象的其他函数,只需要在input后面输入点(.)后,Eclipse会提示input对象支持的所有函数,当然有很多我们不关心的函数。我们一般只关心hasNext开头的函数和next开头的函数。其中hasNext开头的函数是用来判断输入缓冲区中是否有下一个数据;next开头的是读取下一个数据。
**关于Scanner类的其他函数,以后会用到,有兴趣你们可以通过阅读在线文档先了解一下。**
## 3. 标识符、变量、常量
### 3.1. 与C语言一致的
1. Identifiers:标识符
2. Variables:变量
3. Declaring Variables:变量声明
4. Assignment Statements:赋值语句
5. Declaring and Initializing in One Step:变量声明与赋值用一行语句
上面这些和C保持一致,我们只看看常量的声明。
### 3.2. 常量的声明
Java常量声明与C完全不一样,想一想C的常量如何声明的?下面是Java常量的语法:
final datatype CONSTANTNAME = VALUE;  
例如:
```java
final double PI = 3.14;
final String ERROR="ERROR";
```
### 3.3. 命名规则
其实只要是符合标识符的规则就是合法的变量名、常量名、函数名、类名;但是为了阅读方便,大家有个对命名大小写的共识,一般是这样:
1. 常量:全部大写;
2. 变量:首字母小写;
3. 类名(接口名):首字母大写,如果有多个单词,每个单词的首字母大写;
4. 函数名:首字母小写。
## 4. 基本数据类型
### 4.1. 数值类型
| 类型 | 存储大小(bit) | 说明 |
| ------ | --------- | --- |
| byte | 8 | |
| short | 16 | |
| int | 32 | |
| long | 64 | |
| float | 32 | |
| double | 64 | |
C语言中有uint、ulong等带u开头的整形类型,Java中有吗?
**注意,Java的类型中所有小写开头的类型都对应一个大写开头的类型。例如int和Integer这两个类型是不同的,关于大写开头的类型我们以后再讲。这里只需要记住小写开头的类型叫做基本类型,与C的类型保持一致;大写开头的对应类型叫做封装类型(类)是面向对象的。**
Scanner对象有相应读取这些数据类型的函数,请自己尝试一下。
### 4.2. 数字运算
基本运算符、除法(整除与浮点除)、取余与C保持一致。
试一试,如果使用System.out输出一个浮点数,要求保留小数点后的位数应该如何操作。
### 4.3. 数值类型的字面量(Literals
字面量的含义是语句中直接写入整形数值或者是浮点数值的时候,这个数值表达的数据类型或者是赋值规则。例如:
```java
byte a = 100;
byte b = 200;
int c = 300;
int d = 5000;
float e = 33.3;
double f = 33.3;
```
上述代码中,第二行代码是非法的;第五行代码也是非法的;为什么?
规则:
1. 对于整形赋值,只要字面量表达的数值不超过变量类型的取值范围就是合法的;
2. 对于带小数的字面量,缺省的类型是double,因此如果赋值给float的类型的变量会出错,正确的做法是在字面量后面加上F。
```java
float e = 33.3F;
```
科学计数法:例如:1.23456e-2
### 4.4. 扩展赋值语法:Augmented Assignment Operators
![](img/20230303162645.png)
和C语言保持一致。
### 4.5. 自增、自减操作
![](img/20230303162710.png)
与C保持一致
### 4.6. 数值类型转换
隐式转换:首先看被赋值的变量;再看表达式。表达式向高精度看齐,最终符合被赋值变量的精度。
包括计算时的精度匹配以及强制类型转换,保持与C一致。
## 5. 本章重点
1. 如何打印输出:有很多同名的打印函数(函数重载overload);printprintlnprintf函数;与C有什么区别;
2. 字符串与其他类型连接通过+号;
3. 如何读取键盘输入,以及赋值。注意不同的类型使用不同的函数;
4. 如何判断是否还有没有读取的数据(hasNext函数XXX);
5. 基本数据类型:全部都是小写,以后会学习对应大写的包装类型;都是有符号的;
6. 如何声明常量(final);
7. 类型转换以及规则。