mirror of
https://gitee.com/gaohongy/Java-Book.git
synced 2026-07-16 11:23:50 +00:00
完成第二章的内容
This commit is contained in:
+21
-20
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
如果从C语言出发,需要建立一个结构体来描述圆。
|
如果从C语言出发,需要建立一个结构体来描述圆。
|
||||||
|
|
||||||
```c {.line-numbers}
|
```c
|
||||||
struct Circle
|
struct Circle
|
||||||
{
|
{
|
||||||
float x; // X坐标
|
float x; // X坐标
|
||||||
@@ -23,14 +23,13 @@ struct Circle
|
|||||||
|
|
||||||
上面只是定义了一个结构体(抽象,代表所有圆),但是还不存在一个真正的圆的实例(具体的对象),因此需要定义一个变量,其类型是Circle这个结构体。
|
上面只是定义了一个结构体(抽象,代表所有圆),但是还不存在一个真正的圆的实例(具体的对象),因此需要定义一个变量,其类型是Circle这个结构体。
|
||||||
|
|
||||||
```c {.line-numbers}
|
```c
|
||||||
struct Circle c1;
|
struct Circle c1;
|
||||||
```
|
```
|
||||||
|
|
||||||
如果要改变c1这个圆结构变量的值我们有两种方法,首先是直接赋值。
|
如果要改变c1这个圆结构变量的值我们有两种方法,首先是直接赋值。
|
||||||
|
|
||||||
|
```c
|
||||||
```c {.line-numbers}
|
|
||||||
struct Circle c1;
|
struct Circle c1;
|
||||||
c1.x = 0;
|
c1.x = 0;
|
||||||
c1.y = 1;
|
c1.y = 1;
|
||||||
@@ -41,7 +40,7 @@ struct Circle c1;
|
|||||||
|
|
||||||
另外还可以用函数的方式来改变结构体的值。
|
另外还可以用函数的方式来改变结构体的值。
|
||||||
|
|
||||||
```c {.line-numbers}
|
```c
|
||||||
/**
|
/**
|
||||||
* 给圆设定初始值
|
* 给圆设定初始值
|
||||||
* @param c 圆结构的指针
|
* @param c 圆结构的指针
|
||||||
@@ -58,7 +57,7 @@ void setCircle(struct Circle *c, float x, float y, float r) {
|
|||||||
|
|
||||||
另外我们一次性的打印整个圆的数据,这样我们最好需要一个函数。
|
另外我们一次性的打印整个圆的数据,这样我们最好需要一个函数。
|
||||||
|
|
||||||
```c {.line-numbers}
|
```c
|
||||||
/**
|
/**
|
||||||
* 打印
|
* 打印
|
||||||
* @param c
|
* @param c
|
||||||
@@ -70,7 +69,7 @@ void printCircle(struct Circle *c) {
|
|||||||
|
|
||||||
把所有代码放在一起:
|
把所有代码放在一起:
|
||||||
|
|
||||||
```c {.line-numbers}
|
```c
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
|
||||||
@@ -125,7 +124,7 @@ int main() {
|
|||||||
|
|
||||||
例如,人这个对象有固有的特性(性别、年龄、身高、体重。。。)这些和圆的坐标和半径对应,都表示一个对象的特性;但是人可以说话,可以运动(动作、行为,相当于函数);而结构体变量的圆不能自己动作,只能依靠外部的函数进行动作。如果圆可以自己动作,例如让圆这个对象自己打印输出,这样不就可以和生活中的对象联系起来了?
|
例如,人这个对象有固有的特性(性别、年龄、身高、体重。。。)这些和圆的坐标和半径对应,都表示一个对象的特性;但是人可以说话,可以运动(动作、行为,相当于函数);而结构体变量的圆不能自己动作,只能依靠外部的函数进行动作。如果圆可以自己动作,例如让圆这个对象自己打印输出,这样不就可以和生活中的对象联系起来了?
|
||||||
|
|
||||||
```c {.line-numbers}
|
```c
|
||||||
struct Circle
|
struct Circle
|
||||||
{
|
{
|
||||||
float x; // X坐标
|
float x; // X坐标
|
||||||
@@ -151,7 +150,7 @@ c1.print(); // C语言无法做到
|
|||||||
|
|
||||||
接下来我们使用java来实现上述的功能,这里主要是要把相关的函数作为结构体的一个部分。
|
接下来我们使用java来实现上述的功能,这里主要是要把相关的函数作为结构体的一个部分。
|
||||||
|
|
||||||
```c {.line-numbers}
|
```c
|
||||||
/**
|
/**
|
||||||
* 定义Circle类
|
* 定义Circle类
|
||||||
*
|
*
|
||||||
@@ -211,11 +210,10 @@ public class Circle_Test {
|
|||||||
|
|
||||||
命令行中执行:
|
命令行中执行:
|
||||||
|
|
||||||
```bash {.line-numbers}
|
```bash
|
||||||
javac Circle_Test.java
|
javac Circle_Test.java
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
发现生成了两个文件
|
发现生成了两个文件
|
||||||

|

|
||||||
|
|
||||||
@@ -223,13 +221,13 @@ javac Circle_Test.java
|
|||||||
|
|
||||||
接下来使用命令行
|
接下来使用命令行
|
||||||
|
|
||||||
```bash {.line-numbers}
|
```bash
|
||||||
java Circle_Test
|
java Circle_Test
|
||||||
```
|
```
|
||||||
|
|
||||||
运行刚刚编译后的代码,得到结果
|
运行刚刚编译后的代码,得到结果
|
||||||
|
|
||||||
```bash {.line-numbers}
|
```bash
|
||||||
The position x=0, y=1, radius=11.200000!
|
The position x=0, y=1, radius=11.200000!
|
||||||
The position x=1, y=1, radius=3.300000!
|
The position x=1, y=1, radius=3.300000!
|
||||||
```
|
```
|
||||||
@@ -352,7 +350,7 @@ Eclipse 是一个开放的框架,基于Eclipse框架的有很多不同语言
|
|||||||
|
|
||||||
完成后,会打开一个新的类:
|
完成后,会打开一个新的类:
|
||||||
|
|
||||||
```java {.line-numbers}
|
```java
|
||||||
package first;
|
package first;
|
||||||
|
|
||||||
public class Hello {
|
public class Hello {
|
||||||
@@ -367,7 +365,7 @@ public class Hello {
|
|||||||
|
|
||||||
接下来我们修改这个类框架,主要是修改main函数部分,结果如下:
|
接下来我们修改这个类框架,主要是修改main函数部分,结果如下:
|
||||||
|
|
||||||
```java {.line-numbers}
|
```java
|
||||||
package first;
|
package first;
|
||||||
|
|
||||||
public class Hello {
|
public class Hello {
|
||||||
@@ -379,6 +377,7 @@ public class Hello {
|
|||||||
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
保存(ctl+s)后,可以运行看看结果:
|
保存(ctl+s)后,可以运行看看结果:
|
||||||
|
|
||||||

|

|
||||||
@@ -413,6 +412,7 @@ public class Hello {
|
|||||||
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
注意,第一行并没有 package 这个申明。在看看文件系统:
|
注意,第一行并没有 package 这个申明。在看看文件系统:
|
||||||
|
|
||||||

|

|
||||||
@@ -429,7 +429,7 @@ Hello.java 这个文件的确在src文件夹中。
|
|||||||
|
|
||||||
我们再来回顾以下上面最简单的Hello world:
|
我们再来回顾以下上面最简单的Hello world:
|
||||||
|
|
||||||
```java {.line-numbers}
|
```java
|
||||||
package first;
|
package first;
|
||||||
|
|
||||||
public class Hello {
|
public class Hello {
|
||||||
@@ -441,6 +441,7 @@ public class Hello {
|
|||||||
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
1. package:包描述,该源代码在那个包,对应src文件夹中的字文件夹。如果有多个层级的包(src子文件夹中的子文件夹),使用点(.)来分割包名。尝试一下在包下面建立子包后package是如何描述的。package不是必须的,如果java文件在src中,package可以省略,这时表示缺省包。
|
1. package:包描述,该源代码在那个包,对应src文件夹中的字文件夹。如果有多个层级的包(src子文件夹中的子文件夹),使用点(.)来分割包名。尝试一下在包下面建立子包后package是如何描述的。package不是必须的,如果java文件在src中,package可以省略,这时表示缺省包。
|
||||||
2. 一般来说,一个Java文件包含一个类(Class)结构,如果有多个并列的Class结构,只能有一个描述成public。关于public的含义后面会讲到。
|
2. 一般来说,一个Java文件包含一个类(Class)结构,如果有多个并列的Class结构,只能有一个描述成public。关于public的含义后面会讲到。
|
||||||
3. 类名(或者描述成public的类名),这个例子是Hello,必须和主文件名一致。
|
3. 类名(或者描述成public的类名),这个例子是Hello,必须和主文件名一致。
|
||||||
@@ -468,7 +469,7 @@ public class Hello {
|
|||||||
|
|
||||||
语法错误,编译的时候发现,例如:
|
语法错误,编译的时候发现,例如:
|
||||||
|
|
||||||
```java {.line-numbers}
|
```java
|
||||||
public class ShowSyntaxErrors {
|
public class ShowSyntaxErrors {
|
||||||
public static main(String[] args) {
|
public static main(String[] args) {
|
||||||
System.out.println("Welcome to Java);
|
System.out.println("Welcome to Java);
|
||||||
@@ -480,7 +481,7 @@ public class ShowSyntaxErrors {
|
|||||||
|
|
||||||
运行时错误,运行时产生的错误,例如空对象操作、0作为除数、文件不存在等。运行时错误是我们需要特别关注的,因为会导致程序的流程异常,产生意想不到的结果。例如下面这个例子:
|
运行时错误,运行时产生的错误,例如空对象操作、0作为除数、文件不存在等。运行时错误是我们需要特别关注的,因为会导致程序的流程异常,产生意想不到的结果。例如下面这个例子:
|
||||||
|
|
||||||
```java {.line-numbers}
|
```java
|
||||||
public class ShowRuntimeErrors {
|
public class ShowRuntimeErrors {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
System.out.println(1 / 0);
|
System.out.println(1 / 0);
|
||||||
@@ -494,7 +495,7 @@ public class ShowRuntimeErrors {
|
|||||||
|
|
||||||
逻辑错误,简单说来就是语法没错、也没有运行时错误(异常),但是结果错误了。通常是编程者的算法错了,例如:
|
逻辑错误,简单说来就是语法没错、也没有运行时错误(异常),但是结果错误了。通常是编程者的算法错了,例如:
|
||||||
|
|
||||||
```java {.line-numbers}
|
```java
|
||||||
public class ShowLogicErrors {
|
public class ShowLogicErrors {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
System.out.println("Celsius 35 is Fahrenheit degree ");
|
System.out.println("Celsius 35 is Fahrenheit degree ");
|
||||||
@@ -513,7 +514,7 @@ public class ShowLogicErrors {
|
|||||||
|
|
||||||
代码如下:
|
代码如下:
|
||||||
|
|
||||||
```java {.line-numbers}
|
```java
|
||||||
public class Debug {
|
public class Debug {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|||||||
+10
-9
@@ -2,7 +2,6 @@ Java基础(第二章)
|
|||||||
|
|
||||||
## 1. 如何打印输出
|
## 1. 如何打印输出
|
||||||
|
|
||||||
|
|
||||||
**这一章中,我们使用面向过程(C语言的方式)来了解Java的基本语法。虽然说是和面向对象无关,但是我们需要一个函数入口(main)函数,这个函数上一章讲过,有固定的格式,且这个函数必须定义在一个Public类中。**
|
**这一章中,我们使用面向过程(C语言的方式)来了解Java的基本语法。虽然说是和面向对象无关,但是我们需要一个函数入口(main)函数,这个函数上一章讲过,有固定的格式,且这个函数必须定义在一个Public类中。**
|
||||||
|
|
||||||
### 1.1. ComputeArea.java
|
### 1.1. ComputeArea.java
|
||||||
@@ -11,7 +10,7 @@ Java基础(第二章)
|
|||||||
|
|
||||||
ComputeArea.java
|
ComputeArea.java
|
||||||
|
|
||||||
```java {.line-numbers}
|
```java
|
||||||
public class ComputeArea {
|
public class ComputeArea {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
double radius = 0.0; // Declare radius
|
double radius = 0.0; // Declare radius
|
||||||
@@ -71,7 +70,7 @@ C使用scanf函数配合一套字符串规则实现各种数据类型的输入
|
|||||||
|
|
||||||
### 2.1. ComputeAreaWithConsoleInput.java
|
### 2.1. ComputeAreaWithConsoleInput.java
|
||||||
|
|
||||||
```java {.line-numbers}
|
```java
|
||||||
import java.util.Scanner; // Scanner is in the java.util package
|
import java.util.Scanner; // Scanner is in the java.util package
|
||||||
|
|
||||||
public class ComputeAreaWithConsoleInput {
|
public class ComputeAreaWithConsoleInput {
|
||||||
@@ -91,6 +90,7 @@ public class ComputeAreaWithConsoleInput {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
注意第一行的 import ..... 这个语句,这是把Scanner所在的包引入进来,相当于C的include语句。如果不写第一行,Eclipse会在地6行的 Scanner位置错误(红色下划线),这是只需要把鼠标移动到 Scanner 上面,会出现quike fix 的建议,如下图。这时只需要点击:Import 'Scanner' (java.util) 就可以了,Eclipse会自动加上import语句。
|
注意第一行的 import ..... 这个语句,这是把Scanner所在的包引入进来,相当于C的include语句。如果不写第一行,Eclipse会在地6行的 Scanner位置错误(红色下划线),这是只需要把鼠标移动到 Scanner 上面,会出现quike fix 的建议,如下图。这时只需要点击:Import 'Scanner' (java.util) 就可以了,Eclipse会自动加上import语句。
|
||||||
|
|
||||||

|

|
||||||
@@ -113,7 +113,6 @@ public class ComputeAreaWithConsoleInput {
|
|||||||
|
|
||||||
## 3. 标识符、变量、常量
|
## 3. 标识符、变量、常量
|
||||||
|
|
||||||
|
|
||||||
### 3.1. 与C语言一致的
|
### 3.1. 与C语言一致的
|
||||||
|
|
||||||
1. Identifiers:标识符
|
1. Identifiers:标识符
|
||||||
@@ -132,7 +131,7 @@ final datatype CONSTANTNAME = VALUE;
|
|||||||
|
|
||||||
例如:
|
例如:
|
||||||
|
|
||||||
```java {.line-numbers}
|
```java
|
||||||
final int PI = 3.14;
|
final int PI = 3.14;
|
||||||
final String ERROR="ERROR";
|
final String ERROR="ERROR";
|
||||||
```
|
```
|
||||||
@@ -151,13 +150,13 @@ final String ERROR="ERROR";
|
|||||||
### 4.1. 数值类型
|
### 4.1. 数值类型
|
||||||
|
|
||||||
| 类型 | 存储大小(bit) | 说明 |
|
| 类型 | 存储大小(bit) | 说明 |
|
||||||
|--------|-----------|----|
|
| ------ | --------- | --- |
|
||||||
| byte | 8 | |
|
| byte | 8 | |
|
||||||
| short | 16 | |
|
| short | 16 | |
|
||||||
| int | 32 | |
|
| int | 32 | |
|
||||||
| long | 64 | |
|
| long | 64 | |
|
||||||
| float | 32 | |
|
| float | 32 | |
|
||||||
| double | 64 |
|
| double | 64 | |
|
||||||
|
|
||||||
C语言中有uint、ulong等带u开头的整形类型,Java中有吗?
|
C语言中有uint、ulong等带u开头的整形类型,Java中有吗?
|
||||||
|
|
||||||
@@ -175,7 +174,7 @@ Scanner对象有相应读取这些数据类型的函数,请自己尝试一下
|
|||||||
|
|
||||||
字面量的含义是语句中直接写入整形数值或者是浮点数值的时候,这个数值表达的数据类型或者是赋值规则。例如:
|
字面量的含义是语句中直接写入整形数值或者是浮点数值的时候,这个数值表达的数据类型或者是赋值规则。例如:
|
||||||
|
|
||||||
```java {.line-numbers}
|
```java
|
||||||
byte a = 100;
|
byte a = 100;
|
||||||
byte b = 200;
|
byte b = 200;
|
||||||
int c = 300;
|
int c = 300;
|
||||||
@@ -183,6 +182,7 @@ Scanner对象有相应读取这些数据类型的函数,请自己尝试一下
|
|||||||
float e = 33.3;
|
float e = 33.3;
|
||||||
double f = 33.3;
|
double f = 33.3;
|
||||||
```
|
```
|
||||||
|
|
||||||
上述代码中,第二行代码是非法的;第五行代码也是非法的;为什么?
|
上述代码中,第二行代码是非法的;第五行代码也是非法的;为什么?
|
||||||
|
|
||||||
规则:
|
规则:
|
||||||
@@ -190,9 +190,10 @@ Scanner对象有相应读取这些数据类型的函数,请自己尝试一下
|
|||||||
1. 对于整形赋值,只要字面量表达的数值不超过变量类型的取值范围就是合法的;
|
1. 对于整形赋值,只要字面量表达的数值不超过变量类型的取值范围就是合法的;
|
||||||
2. 对于带小数的字面量,缺省的类型是double,因此如果赋值给float的类型的变量会出错,正确的做法是在字面量后面加上F。
|
2. 对于带小数的字面量,缺省的类型是double,因此如果赋值给float的类型的变量会出错,正确的做法是在字面量后面加上F。
|
||||||
|
|
||||||
```java {.line-numbers}
|
```java
|
||||||
float e = 33.3F;
|
float e = 33.3F;
|
||||||
```
|
```
|
||||||
|
|
||||||
科学计数法:例如:1.23456e-2
|
科学计数法:例如:1.23456e-2
|
||||||
|
|
||||||
### 4.4. 扩展赋值语法:Augmented Assignment Operators
|
### 4.4. 扩展赋值语法:Augmented Assignment Operators
|
||||||
|
|||||||
+3
-4
@@ -29,17 +29,16 @@ Java的布尔类型和C保持一致,基本的运算符也和C保持一致。
|
|||||||
例如:0B 和 0A 代表两个byte,转换成位是:
|
例如:0B 和 0A 代表两个byte,转换成位是:
|
||||||
|
|
||||||
| 字节1(0x08) | 字节2(0x07) | 说明 |
|
| 字节1(0x08) | 字节2(0x07) | 说明 |
|
||||||
| ----------- | ----------- | ------------ |
|
| --------- | --------- | ------ |
|
||||||
| 0000-1000 | 0000-0111 | 对应的二进制 |
|
| 0000-1000 | 0000-0111 | 对应的二进制 |
|
||||||
|
|
||||||
| 位操作 | 结果 | 说明 |
|
| 位操作 | 结果 | 说明 |
|
||||||
| ------------ | --------- | ------------------------------ |
|
| ------------ | --------- | --------------- |
|
||||||
| 0x0A & 0x0B | 0000-1000 | 按照每一位对应进行与运算的结果 |
|
| 0x0A & 0x0B | 0000-1000 | 按照每一位对应进行与运算的结果 |
|
||||||
| 0x0A \| 0x0B | 0000-1111 | 按照每一位对应进行或运算的结果 |
|
| 0x0A \| 0x0B | 0000-1111 | 按照每一位对应进行或运算的结果 |
|
||||||
|
|
||||||
**位操作作为了解。**
|
**位操作作为了解。**
|
||||||
|
|
||||||
|
|
||||||
### 1.4. 选择语句
|
### 1.4. 选择语句
|
||||||
|
|
||||||
略
|
略
|
||||||
@@ -54,7 +53,7 @@ Java的布尔类型和C保持一致,基本的运算符也和C保持一致。
|
|||||||
|
|
||||||
这个方式在书上没有讲,在考试中可能会遇到这种情况。
|
这个方式在书上没有讲,在考试中可能会遇到这种情况。
|
||||||
|
|
||||||
```java {.line-numbers}
|
```java
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+29
-16
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
实例:
|
实例:
|
||||||
|
|
||||||
```java {.line-numbers}
|
```java
|
||||||
Math.ceil(2.1) returns 3.0
|
Math.ceil(2.1) returns 3.0
|
||||||
Math.ceil(2.0) returns 2.0
|
Math.ceil(2.0) returns 2.0
|
||||||
Math.ceil(-2.0) returns –2.0
|
Math.ceil(-2.0) returns –2.0
|
||||||
@@ -54,16 +54,16 @@ Math.round(-2.6) returns -3
|
|||||||
2. abs(a) Returns the absolute value of the parameter.
|
2. abs(a) Returns the absolute value of the parameter.
|
||||||
3. random() Returns a random double value in the range \[0.0, 1.0).
|
3. random() Returns a random double value in the range \[0.0, 1.0).
|
||||||
|
|
||||||
|
|
||||||
实例:
|
实例:
|
||||||
|
|
||||||
```java {.line-numbers}
|
```java
|
||||||
Math.max(2, 3) returns 3
|
Math.max(2, 3) returns 3
|
||||||
Math.max(2.5, 3) returns 3.0
|
Math.max(2.5, 3) returns 3.0
|
||||||
Math.min(2.5, 3.6) returns 2.5
|
Math.min(2.5, 3.6) returns 2.5
|
||||||
Math.abs(-2) returns 2
|
Math.abs(-2) returns 2
|
||||||
Math.abs(-2.1) returns 2.1
|
Math.abs(-2.1) returns 2.1
|
||||||
```
|
```
|
||||||
|
|
||||||
### 1.3. The random Method
|
### 1.3. The random Method
|
||||||
|
|
||||||
`Math.random();` 函数生成一个0~1之间的double类型的数,包含0,但是不包含1。
|
`Math.random();` 函数生成一个0~1之间的double类型的数,包含0,但是不包含1。
|
||||||
@@ -78,14 +78,14 @@ char类型是有序的(类似整形),整形可以使用的运算符都可
|
|||||||
|
|
||||||
### 2.1. char和整形的转换
|
### 2.1. char和整形的转换
|
||||||
|
|
||||||
```java {.line-numbers}
|
```java
|
||||||
int i = 'a'; // Same as int i = (int)'a';
|
int i = 'a'; // Same as int i = (int)'a';
|
||||||
char c = 97; // Same as char c = (char)97;
|
char c = 97; // Same as char c = (char)97;
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2.2. char的比较
|
### 2.2. char的比较
|
||||||
|
|
||||||
```java {.line-numbers}
|
```java
|
||||||
if (ch >= 'A' && ch <= 'Z')
|
if (ch >= 'A' && ch <= 'Z')
|
||||||
System.out.println(ch + " is an uppercase letter");
|
System.out.println(ch + " is an uppercase letter");
|
||||||
else if (ch >= 'a' && ch <= 'z')
|
else if (ch >= 'a' && ch <= 'z')
|
||||||
@@ -93,7 +93,9 @@ char c = 97; // Same as char c = (char)97;
|
|||||||
else if (ch >= '0' && ch <= '9')
|
else if (ch >= '0' && ch <= '9')
|
||||||
System.out.println(ch + " is a numeric character");
|
System.out.println(ch + " is a numeric character");
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2.3. 字符类型的相关函数
|
### 2.3. 字符类型的相关函数
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
上述这些函数不能直接调用,而是在 Character 这个类中,因此如果你要调用上述的函数,需要使用 Character.xxx 这样的方式。所有的函数都是静态函数,静态函数,关于静态函数我们会在学习类的时候进行学习,目前我们用到的都是静态函数。
|
上述这些函数不能直接调用,而是在 Character 这个类中,因此如果你要调用上述的函数,需要使用 Character.xxx 这样的方式。所有的函数都是静态函数,静态函数,关于静态函数我们会在学习类的时候进行学习,目前我们用到的都是静态函数。
|
||||||
@@ -104,7 +106,7 @@ char c = 97; // Same as char c = (char)97;
|
|||||||
|
|
||||||
字符串与C完全不一样,Java中的字符串的类型是 String 。注意,以前在Java中出现的类型都是小写开头的,这是第一个大写开头的,因此这个是一个类的类型,而不是普通类型。前面讲到过,类是抽象描述(类似结构体指针),如果来实例化(成为可操作的对象)需要使用new 操作生成一个对象。这里我们看看字符串是如何生成的。
|
字符串与C完全不一样,Java中的字符串的类型是 String 。注意,以前在Java中出现的类型都是小写开头的,这是第一个大写开头的,因此这个是一个类的类型,而不是普通类型。前面讲到过,类是抽象描述(类似结构体指针),如果来实例化(成为可操作的对象)需要使用new 操作生成一个对象。这里我们看看字符串是如何生成的。
|
||||||
|
|
||||||
```java {.line-numbers}
|
```java
|
||||||
public class Main {
|
public class Main {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
String s1 = new String("Hello");
|
String s1 = new String("Hello");
|
||||||
@@ -112,9 +114,10 @@ public class Main {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
第三行代码是生成一个字符串对象,第四行是打印这个字符串。等等,这里和Hello world程序好像有所不同?对的,标准的对象生成应该是按照第三行的方式生成,不过因为String在程序中使用得太频繁了,因此如果写入字符串的字面量,编译器会自动构造一个对象,下面的代码也是正确的:
|
第三行代码是生成一个字符串对象,第四行是打印这个字符串。等等,这里和Hello world程序好像有所不同?对的,标准的对象生成应该是按照第三行的方式生成,不过因为String在程序中使用得太频繁了,因此如果写入字符串的字面量,编译器会自动构造一个对象,下面的代码也是正确的:
|
||||||
|
|
||||||
```java {.line-numbers}
|
```java
|
||||||
public class Main {
|
public class Main {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
String s1 = "Hello";
|
String s1 = "Hello";
|
||||||
@@ -122,15 +125,17 @@ public class Main {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
或者直接使用字面量作为参数:
|
或者直接使用字面量作为参数:
|
||||||
|
|
||||||
```java {.line-numbers}
|
```java
|
||||||
public class Main {
|
public class Main {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
System.out.println("Hello");
|
System.out.println("Hello");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3.2. 字符串操作
|
### 3.2. 字符串操作
|
||||||
|
|
||||||
既然字符串是一个对象,那么就可以用对象的方式来操作字符串。在上述例子中,试试在 s1 这个变量后面输入一个点(.),Eclipse将提示该对象上面的属性和方法(有括号的是方法\\函数,没有括号的是属性\\对象中的变量)。
|
既然字符串是一个对象,那么就可以用对象的方式来操作字符串。在上述例子中,试试在 s1 这个变量后面输入一个点(.),Eclipse将提示该对象上面的属性和方法(有括号的是方法\\函数,没有括号的是属性\\对象中的变量)。
|
||||||
@@ -141,30 +146,32 @@ public class Main {
|
|||||||
|
|
||||||
上述这些函数是在数据库对象上面进行调用的,例如:
|
上述这些函数是在数据库对象上面进行调用的,例如:
|
||||||
|
|
||||||
```java {.line-numbers}
|
```java
|
||||||
String sA = "Hello world!";
|
String sA = "Hello world!";
|
||||||
int len = sA.length();
|
int len = sA.length();
|
||||||
char c = sA.charAt(1);
|
char c = sA.charAt(1);
|
||||||
String sB = sA.toUpperCase();
|
String sB = sA.toUpperCase();
|
||||||
String sC = sA.trim();
|
String sC = sA.trim();
|
||||||
```
|
```
|
||||||
|
|
||||||
这里不可能解释所有字符串对象的函数,请参考在线文档。
|
这里不可能解释所有字符串对象的函数,请参考在线文档。
|
||||||
|
|
||||||
#### 3.2.2. 字符串连接
|
#### 3.2.2. 字符串连接
|
||||||
|
|
||||||
字符串连接可以使用算术运算符(+),也可以使用对象函数:
|
字符串连接可以使用算术运算符(+),也可以使用对象函数:
|
||||||
|
|
||||||
```java {.line-numbers}
|
```java
|
||||||
String sA = "Hello";
|
String sA = "Hello";
|
||||||
String sB = "World";
|
String sB = "World";
|
||||||
System.out.println(sA.concat(" ").concat(sB).concat("!"));
|
System.out.println(sA.concat(" ").concat(sB).concat("!"));
|
||||||
System.out.println(sA + " " + sB + "!");
|
System.out.println(sA + " " + sB + "!");
|
||||||
```
|
```
|
||||||
|
|
||||||
**注意,concat 函数返回的是字符串对象,因此concat函数后面可以使用任何的字符串对象的函数。**
|
**注意,concat 函数返回的是字符串对象,因此concat函数后面可以使用任何的字符串对象的函数。**
|
||||||
|
|
||||||
另外,字符串可以和数值类型的变量或者是字面量进行连接:
|
另外,字符串可以和数值类型的变量或者是字面量进行连接:
|
||||||
|
|
||||||
```java {.line-numbers}
|
```java
|
||||||
public class Main {
|
public class Main {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
String sA = "Hello";
|
String sA = "Hello";
|
||||||
@@ -172,13 +179,14 @@ public class Main {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**其实,字符串可以和几乎所有类型的变量或者字面量进行连接,这一点我们在后面还会遇到。更多的原理要我们学了类的继承才能理解。**
|
**其实,字符串可以和几乎所有类型的变量或者字面量进行连接,这一点我们在后面还会遇到。更多的原理要我们学了类的继承才能理解。**
|
||||||
|
|
||||||
#### 3.2.3. 从控制台读取字符串
|
#### 3.2.3. 从控制台读取字符串
|
||||||
|
|
||||||
前面学习了如何从控制台读取数值类型的值,这里我们看看如何读取字符串/字符。
|
前面学习了如何从控制台读取数值类型的值,这里我们看看如何读取字符串/字符。
|
||||||
|
|
||||||
```java {.line-numbers}
|
```java
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
@@ -195,6 +203,7 @@ public class Main {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
运行一下这个代码,输入三个个字符串,字符串间需要使用空格分割,看看结果是什么?
|
运行一下这个代码,输入三个个字符串,字符串间需要使用空格分割,看看结果是什么?
|
||||||
|
|
||||||
next() 是以空格区分字符串的,如果我们需要读取一段字符串,本身包含空格,这就需要使用 nextLine() 这个函数。试试把next() 改成 nextLine() 会是什么结果。nextLine()是以回车进行区分的。
|
next() 是以空格区分字符串的,如果我们需要读取一段字符串,本身包含空格,这就需要使用 nextLine() 这个函数。试试把next() 改成 nextLine() 会是什么结果。nextLine()是以回车进行区分的。
|
||||||
@@ -225,7 +234,7 @@ next() 是以空格区分字符串的,如果我们需要读取一段字符串
|
|||||||
|
|
||||||
这时我们需要使用到相应数值类型的类类型(包装类型),而不是简单的类型了。关于包装类型我们后面会讲到,这里先了解一下。
|
这时我们需要使用到相应数值类型的类类型(包装类型),而不是简单的类型了。关于包装类型我们后面会讲到,这里先了解一下。
|
||||||
|
|
||||||
```java {.line-numbers}
|
```java
|
||||||
public class Main {
|
public class Main {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
int a = Integer.parseInt("1");
|
int a = Integer.parseInt("1");
|
||||||
@@ -235,6 +244,7 @@ public class Main {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
这里 Interger 或者是 Float 是一个类,而非对象。我们把在类上面可以直接调用的方法(不需要实例化成对象),叫做静态方法。关于静态方法,后面学到类的时候还会讲解。
|
这里 Interger 或者是 Float 是一个类,而非对象。我们把在类上面可以直接调用的方法(不需要实例化成对象),叫做静态方法。关于静态方法,后面学到类的时候还会讲解。
|
||||||
|
|
||||||
**parseXXX 方法和 valueOf 方法都可以返回相应字符串对应的数值类型(看你是在哪个类型上调用的),区别是 valueOf 返回的是包装类型,parseXXX返回的是基本类型。**
|
**parseXXX 方法和 valueOf 方法都可以返回相应字符串对应的数值类型(看你是在哪个类型上调用的),区别是 valueOf 返回的是包装类型,parseXXX返回的是基本类型。**
|
||||||
@@ -245,23 +255,25 @@ public class Main {
|
|||||||
|
|
||||||
有很多方式,最简单的是加上一个空字符串(没有内容的字符串),例如:
|
有很多方式,最简单的是加上一个空字符串(没有内容的字符串),例如:
|
||||||
|
|
||||||
```java {.line-numbers}
|
```java
|
||||||
String sA = 100 + "";
|
String sA = 100 + "";
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 3.2.8. 格式化字符串
|
#### 3.2.8. 格式化字符串
|
||||||
|
|
||||||
格式化字符串如同C语言的printf方法,甚至连占位符和格式方法都一模一样。如果要输出一个字符串,可以使用 System.out.printf 方法。
|
格式化字符串如同C语言的printf方法,甚至连占位符和格式方法都一模一样。如果要输出一个字符串,可以使用 System.out.printf 方法。
|
||||||
|
|
||||||
```java {.line-numbers}
|
```java
|
||||||
public class Main {
|
public class Main {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
System.out.printf("Hello, my name is %s, and %d years old.\n", "Danny", 20);
|
System.out.printf("Hello, my name is %s, and %d years old.\n", "Danny", 20);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
当然,如果不想输出字符串,而需要对中间的结果进行格式化应该如何?
|
当然,如果不想输出字符串,而需要对中间的结果进行格式化应该如何?
|
||||||
|
|
||||||
```java {.line-numbers}
|
```java
|
||||||
public class Main {
|
public class Main {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
String a = String.format("Hello, my name is %s, and %d years old.\n", "Danny", 20);
|
String a = String.format("Hello, my name is %s, and %d years old.\n", "Danny", 20);
|
||||||
@@ -269,6 +281,7 @@ public class Main {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
下面是占位符列表:
|
下面是占位符列表:
|
||||||
|
|
||||||

|

|
||||||
|
|||||||
+335
-42
@@ -1,76 +1,369 @@
|
|||||||
Java的函数和 C 类似,但因为Java是面向对象的语言,所以又有很多扩展的地方,我们这里主要对其特殊的地方进行讲解。
|
Java的函数和 C 类似,但因为Java是面向对象的语言,所以又有很多扩展的地方,我们这里主要对其特殊的地方进行讲解。
|
||||||
|
|
||||||
## 静态函数与非静态函数
|
**广义上讲,函数(function)与过程(procedure)的含义是一样的。在有些语言中(例如Pascal),函数是指有返回值的;过程是指没有返回值的。**
|
||||||
|
|
||||||
|
## 1. 函数
|
||||||
|
|
||||||
到目前为止,我们学习的大多是静态函数。什么是静态函数?简单说来,静态函数是不依附对象就可以直接运行的函数。这个怎么解释?要了解静态与非静态函数的区别,首先需要知道什么是对象。前面说过,类是抽象描述的,如同类型定义;对象是类的一个真实变量(分配了具体的内存)。这种关系如果我们第一章的结构体指针类型和一个分配了存储空间的结构体指针变量。
|
函数的定义和数学上的定义相似,可以理解为函数是一个抽象的算法,当传入一定的参数后,函数可以有一定的返回结果。当然函数不一定都需要返回,但是一定是包含一定的功能和算法,并且产生一定的效果。
|
||||||
|
|
||||||
### 如何计算字符串的长度
|
从更广泛的意义上说,一个应用程序或者是APP都可以说是一个复杂的函数,它们接受输入,通过计算产生一定的效果(输出)。
|
||||||
|
|
||||||
接下来看看C的函数的语义。函数是具备高度抽象的计算功能,需要传入参数后返回或者不返回结果(对数据进行修改)。例如C语言如果需要确定字符串的长度,这个函数的原型(签名)是这样的:
|
### 1.1. 空函数
|
||||||
|
|
||||||
```C {.line-numbers}
|
空函数在语法上将是存在的,例如下面一个Java的空函数:
|
||||||
|
|
||||||
|
```java
|
||||||
|
void nullFunxtion(){
|
||||||
|
// 没有算法,不返回,没有任何功能
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
这个函数虽然在语法上没有问题,也可以通过编译,也能被其他的代码所调用,但是这个函数本身是没有意义的。因为没有算法,没有任何的效果。**这里我们不讨论空函数。**
|
||||||
|
|
||||||
|
### 1.2. 没有返回值的函数
|
||||||
|
|
||||||
|
函数可以没有返回值,但是需要有算法,并且一定产生某些效果(影响)。
|
||||||
|
|
||||||
|
例如:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class Test {
|
||||||
|
|
||||||
|
static int sum = 0;
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
add(10);
|
||||||
|
add(11);
|
||||||
|
System.out.print(sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add(int i) {
|
||||||
|
sum = sum + i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
上面的函数 `static void add(int i)` 这个函数就是没有返回值的,但是函数中的算法有效果:对变量sum进行累加。当然,其他的一些没有返回的值的函数可能产程其他的效果:例如打印、文件输出、网络连接... 这些都是函数产生的影响,也是函数存在的意义。
|
||||||
|
|
||||||
|
### 1.3. 有返回值的函数
|
||||||
|
|
||||||
|
如果函数有返回值,需要确定返回值的类型,这一点和C语言也是一致的。任何的系统预定义类型,和自定义类型(Java中主要是类),都可以作为函数的返回类型。下面是一个简单的例子:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class Test {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.print(add(1, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int add(int i, int j) {
|
||||||
|
return i + j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
print也是一个函数,它的输入参数刚好是add这个函数的返回值,因此这里的结果是11。
|
||||||
|
|
||||||
|
### 1.4. 函数返回多个值
|
||||||
|
|
||||||
|
上面两个例子说明函数有没有返回值都可能产生一定的效果。在某些情况下,一个函数可能会产生多种效果,例如C语言的fwrite(写文件)函数,他的效果是向文件写入一些数据,同时其返回值是表示写入的数据是否成功。也就是说这个函数同有两种结果(返回成功与否,同时写入数据)。
|
||||||
|
|
||||||
|
那一个函数是否可以有多个返回值?在C中,一个函数只能有一个返回值,但是可以通过一些技巧使其具有返回多个值的不同效果,例如:
|
||||||
|
|
||||||
|
1. 传递参数的指针,这样在函数内部可以改变传入参数的值,这是指针传递;
|
||||||
|
|
||||||
|
2. 使用多个全局变量,在函数内是可以改变这些全局变量的值;
|
||||||
|
|
||||||
|
3. 使用结构体返回数据。
|
||||||
|
|
||||||
|
当然还有其他很多方法,使得函数可以返回多个值。
|
||||||
|
|
||||||
|
**注意:Java中没有指针的概念,所以也没有指针传递参数的用法。但是Java有引用,这是后面我们要讨论的问题。**
|
||||||
|
|
||||||
|
Java没有指针,但是有加强的结构体(类-对象)。类与对象我们放在后面来讲,这里我们看一个通过“全局变量”返回多个值的例子:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class Test {
|
||||||
|
|
||||||
|
static int a = 0;
|
||||||
|
static int b = 0;
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.printf("a=%d and b=%d\n", a, b);
|
||||||
|
changeAB();
|
||||||
|
System.out.printf("a=%d and b=%d\n", a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void changeAB() {
|
||||||
|
a = 100;
|
||||||
|
b = 200;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Java并没有真正意义上的“全局变量”,每个变量都被局限到一个类中,类好比一个盒子,把变量(目前是静态变量)、常量(常量都是静态的)和函数(目前是静态函数)包装起来了(封装特性)。在类(这个盒子中)可以自由调用这些静态变量、常量、静态函数。如果在这个盒子外边调用这个类的静态变量、常量、静态函数,就需要先找到这些静态成员的盒子(类),再调用,例如前面使用到的`Math.PI` 常量;`Math.abs(a,b)` 静态函数;上个例子中的 变量 a 和 b(静态变量)。
|
||||||
|
|
||||||
|
上个例子中的函数 changeAB 因为和静态变量在同一个空间(一个类中),因此在前面不用加上类名。当然加上类名也不错,例如:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class Test {
|
||||||
|
|
||||||
|
static int a = 0;
|
||||||
|
static int b = 0;
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.printf("a=%d and b=%d\n", a, b);
|
||||||
|
changeAB();
|
||||||
|
System.out.printf("a=%d and b=%d\n", a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void changeAB() {
|
||||||
|
Test.a = 100;
|
||||||
|
Test.b = 200;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. 静态与非静态(实例化)
|
||||||
|
|
||||||
|
到目前为止,我们学习的大多是静态函数。什么是静态函数?简单说来,静态函数是不依附对象就可以直接运行的函数。这个怎么解释?要了解静态与非静态函数的区别,首先需要知道什么是对象。前面说过,类是抽象描述的,像C语言中的类型定义;对象是类的一个真实变量(分配了具体的内存)。这种关系我们第一章的结构体指针类型和一个分配了存储空间的结构体指针变量中进行了分析。
|
||||||
|
|
||||||
|
同样,静态变量也是不依赖对象存在的,在程序运行的时候就存在,而不需要创建和依附一个对象存在。
|
||||||
|
|
||||||
|
简单的理解,静态函数相当于C语言中的函数;静态变量相当于C语言中的全局变量,只不过Java没有全局变量,都是封装在类这个盒子当中。
|
||||||
|
|
||||||
|
### 2.1. 静态函数与实例函数
|
||||||
|
|
||||||
|
#### 2.1.1. C语言中如何计算字符串的长度
|
||||||
|
|
||||||
|
接下来看看C的函数的语义。例如C语言如果需要确定字符串的长度,这个函数的原型是这样的:
|
||||||
|
|
||||||
|
```C
|
||||||
int strlen(const char *str)
|
int strlen(const char *str)
|
||||||
```
|
```
|
||||||
|
|
||||||
注意,C是非面向对象的,因此它需要知道需要计算哪个字符串的长度。
|
这个函数可以直接调用,有一个参数告诉这个函数是计算哪个字符串的长度。
|
||||||
|
|
||||||
|
#### 2.1.2. Java中如何计算字符串的长度
|
||||||
|
|
||||||
|
注意,C是非面向对象的,因此它需要知道需要计算哪个字符串(数据)的长度。
|
||||||
|
|
||||||
接下来,我们看看Java字符串长度的函数:
|
接下来,我们看看Java字符串长度的函数:
|
||||||
|
|
||||||
```java {.line-numbers}
|
```java
|
||||||
String s = "Hello world!";
|
String s = "Hello world!";
|
||||||
int size = s.length();
|
int size = s.length();
|
||||||
```
|
```
|
||||||
看到区别了吗?Java计算字符串长度的意思是计算自己本身字符串的长度;C是的含义是计算谁的字符串长度。这个就是最根本的区别。
|
|
||||||
|
|
||||||
对象是相关数据与在相关数据上操作函数的集合。
|
看到区别了吗?Java计算字符串长度的意思是计算自己本身对象字符串的长度;C是的含义是计算谁的字符串长度。这个就是最根本的区别。因为Java中的字符串是一个对象,有数据,因此在计算的时候就知道数据在哪里,因此不再需要传入一个字符串的数据。这里的s是一个字符串对象的引用变量,这样`s.length()`的语义是s这个字符串对象的长度(s中本来就就数据),计算自己字符串的长度。
|
||||||
|
|
||||||
|
**对象是相关数据与在相关数据上操作函数的集合。**
|
||||||
|
|
||||||
显然,s这个对象(String类型的实例),本身含有数据(字符串内容),以及相关的操作函数(例如 length 这个函数)。因此length()并不需要传入字符串的参数,因为length()在 s 这个对象上执行,s本身包含数据。
|
显然,s这个对象(String类型的实例),本身含有数据(字符串内容),以及相关的操作函数(例如 length 这个函数)。因此length()并不需要传入字符串的参数,因为length()在 s 这个对象上执行,s本身包含数据。
|
||||||
|
|
||||||
一般说来,需要在对象上执行的函数叫做非静态函数;而不需要对象,直接可以运行的函数叫做静态函数。其实,静态变量也是一样的,后面会做解释。
|
一般说来,需要在对象上执行的函数叫做非静态函数;而不需要对象,直接可以运行的函数叫做静态函数。其实,静态变量也是一样的,后面会做解释。
|
||||||
|
|
||||||
在前面几章中我们大多使用静态函数例如对基本类型(小写开头的类型,非类类型,非包装类型)操作的函数大多是静态函数。想一想为什么?因为基本类型尽量做到与C兼容,不是对象,需要静态函数来对基本类型进行操作。后面会学到基本类型的包装类型(warp类型),本生就是对象,因此可以直接在对象上进行操作。
|
String对象的length()函数是一个实例函数,如果你们看这个函数的代码,发现其并没有static进行修饰。实例函数是只能在实例(对象)上面进行调用,不能在类上面进行调用。很明显,String的类在没有实例化前是一个抽象的模板,并没有保存任何的数据,因此,使用String.length()是没有意义的,也是非法的。
|
||||||
|
|
||||||
想一想,前面学过那些静态函数?
|
#### 2.1.3. String中的静态函数
|
||||||
|
|
||||||
前面章节也有例外,这些大写的类型都是类,一般都会实例化一个对象进行使用,例如:
|
String中一个很有用的函数,就是字符串格式化,我们看看下面这个例子:
|
||||||
|
|
||||||
1. String 类型
|
|
||||||
2. Scanner 类型
|
|
||||||
|
|
||||||
### Java与C语言像吗?
|
|
||||||
|
|
||||||
我们看看一个例子:
|
|
||||||
|
|
||||||
```java {.line-numbers}
|
|
||||||
public class Main {
|
|
||||||
static int size;
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
String s = "Hello world!";
|
|
||||||
size = s.length();
|
|
||||||
|
|
||||||
System.out.printf("String:'%s', size is %d.", s, size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
上面这个例子,如果我们把类定义去掉后变成什么样子?
|
|
||||||
|
|
||||||
```java
|
```java
|
||||||
static int size;
|
public class Test {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
String s = "Hello world!";
|
String string = String.format("Hello %s !\n", "world");
|
||||||
size = s.length();
|
System.out.print(string);
|
||||||
|
}
|
||||||
|
|
||||||
System.out.printf("String:'%s', size is %d.", s, size);
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
看看上面的例子,结构是不是非常像C语言?
|
这个函数和`System.printf`函数一样,都是负责代码格式化,只不过,`String.format`是返回一个格式化后的字符串,`System.printf` 是打印格式化后的字符串。
|
||||||
|
|
||||||
思考一个问题:Java有全局变量吗?如果没有,如何实现全局变量?
|
**一个类中可以同时拥有静态、或者是实例函数;同样可以同时拥有静态变量和实例变量。**
|
||||||
如何调用一个静态的常量或者是变量?包是如何组织的?
|
|
||||||
|
|
||||||
其实,Java没有C那样的全局变量。因为Java所有的代码必须在一个类定义中(一个类在一个包中)。这样调用一个变量(必须是静态的),可以使用 xxx.yyy.Zzz.var 的方式进行调用。其中:xxx.yyy 是包定义,Zzz是类名,var是该类中的一个静态变量。同理,静态函数的调用也可以使用这种方式。这种方式在Java中叫做命名空间(name space),有什么好处?优势是所有的函数、变量、常量等都在一个空间中,不像C语言是全局的;这样即使是同名的变量、常量、函数,只要不再同一个空间中(也不可能在同一个空间中),那么就是合法的。通过空间的方式,相当于多了一个限定,不必给变量、常量、函数取很长的名字来进行区分。反观C语言,你们会看看很长的命名,因为都在全局中,需要保证命名的唯一性。
|
### 2.2. 静态变量
|
||||||
|
|
||||||
|
有static修饰的变量就是静态变量。Java中的静态变量和C的全局变量很相似,不过是封装在一个类中的,在本页面的1.3中的例子讲了静态变量的使用。非动态变量(依附于对象存在的变量)将在类和对象的相关知识点中讲解。
|
||||||
|
|
||||||
|
## 3. 函数签名与函数重载
|
||||||
|
|
||||||
|
在java中,一个函数肯能看起来很复杂,不仅有返回值,还有前面的public和static等修饰(这些修饰是可选的)。函数签名的概念是一个函数的函数名连同其形式参数列表叫做函数签名。
|
||||||
|
|
||||||
|
在一个类中,可能出现两个同名的函数,只要他们的参数列表不同就可以,这种方式叫做函数重载,对比C语言,是没有函数重载的。函数重载避免了C语言中,因为功能相似,而参数名不同需要用多个不同的函数名的问题。大家可以看到C语言的函数名大多很长,其实是因为C的所有函数都是全局存储的(Java是把函数放在盒子Class里,不同的Class中可以存在同名且同参数的函数),另外就是C没有函数重载的机制。
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class TestMethodOverloading {
|
||||||
|
/** Main method */
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// Invoke the max method with int parameters
|
||||||
|
System.out.println("The maximum of 3 and 4 is " + max(3, 4));
|
||||||
|
|
||||||
|
// Invoke the max method with the double parameters
|
||||||
|
System.out.println("The maximum of 3.0 and 5.4 is " + max(3.0, 5.4));
|
||||||
|
|
||||||
|
// Invoke the max method with three double parameters
|
||||||
|
System.out.println("The maximum of 3.0, 5.4, and 10.14 is " + max(3.0, 5.4, 10.14));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return the max of two int values */
|
||||||
|
public static int max(int num1, int num2) {
|
||||||
|
if (num1 > num2)
|
||||||
|
return num1;
|
||||||
|
else
|
||||||
|
return num2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Find the max of two double values */
|
||||||
|
public static double max(double num1, double num2) {
|
||||||
|
if (num1 > num2)
|
||||||
|
return num1;
|
||||||
|
else
|
||||||
|
return num2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return the max of three double values */
|
||||||
|
public static double max(double num1, double num2, double num3) {
|
||||||
|
return max(max(num1, num2), num3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
上面这个例子说明了函数重载的使用,大家可能跟踪调试一下。当调用一个函数的时候,是通过参数类型和参数的个数来确定最终调用哪个函数的。上个例子中的语义并不存在歧义。
|
||||||
|
|
||||||
|
需要注意的是,参数类型不一样的函数重载不是总是成功,例如:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class Test {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int rst1 = add(1, 100);
|
||||||
|
long a = 100;
|
||||||
|
long b = 200;
|
||||||
|
int rst2 = add(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int add(int a, int b) {
|
||||||
|
System.out.println("add version 1 is invoked!");
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long add(long a, long b) {
|
||||||
|
System.out.println("add version 2 is invoked!");
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
上面这个例子中我们希望 `int rst2 = add(a,b)` 调用第二个版本的add函数,但是编译会出错,这是Java的限制,大家需要根据实际情况来判断。
|
||||||
|
|
||||||
|
## 4. 局部变量的访问范围
|
||||||
|
|
||||||
|
> A local variable: a variable defined inside a method.
|
||||||
|
> Scope: the part of the program where the variable can be referenced.
|
||||||
|
> The scope of a local variable starts from its declaration and continues to the end of the block that contains the variable. A local variable must be declared before it can be used.
|
||||||
|
|
||||||
|
> You can declare a local variable with the same name multiple times in different non-nesting blocks in a method, but you cannot declare a local variable twice in nested blocks.
|
||||||
|
|
||||||
|
上面说明了什么叫做局部变量(就是函数中的变量,这个和C的定义是一致的),以及局部变量的访问范围(作用域)。一句话,局部变量的作用域在其定义的时候开始,一致到该语法块结束。
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class Test {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
correctMethod();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void correctMethod() {
|
||||||
|
int x = 1;
|
||||||
|
int y = 1;
|
||||||
|
// i is declared
|
||||||
|
for (int i = 1; i < 10; i++) {
|
||||||
|
x += i;
|
||||||
|
}
|
||||||
|
// i is declared again
|
||||||
|
for (int i = 1; i < 10; i++) {
|
||||||
|
y += i;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.printf("X = %d ; Y = %d", x,y);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
这个例子中,局部变量 x,y 在for循环中是可以访问到的。
|
||||||
|
|
||||||
|
```java
|
||||||
|
public static void incorrectMethod() {
|
||||||
|
int x = 1;
|
||||||
|
int y = 1;
|
||||||
|
for (int i = 1; i < 10; i++) {
|
||||||
|
int x = 0; //这里的x定义非法!
|
||||||
|
x += i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
上面这个例子会显示一个编译错误,提示for循环中定义的x变量与函数中定义的x变量重名了,这时候需要考虑修改一个变量的名字。
|
||||||
|
|
||||||
|
## 5. 访问其他类中的静态函数
|
||||||
|
|
||||||
|
直接借用书上的例子:
|
||||||
|
|
||||||
|
主类
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class TestRandomCharacter {
|
||||||
|
/** Main method */
|
||||||
|
public static void main(String args[]) {
|
||||||
|
final int NUMBER_OF_CHARS = 175;
|
||||||
|
final int CHARS_PER_LINE = 25;
|
||||||
|
|
||||||
|
// Print random characters between 'a' and 'z', 25 chars per line
|
||||||
|
for (int i = 0; i < NUMBER_OF_CHARS; i++) {
|
||||||
|
char ch = RandomCharacter.getRandomLowerCaseLetter();
|
||||||
|
if ((i + 1) % CHARS_PER_LINE == 0)
|
||||||
|
System.out.println(ch);
|
||||||
|
else
|
||||||
|
System.out.print(ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
使用 `RandomCharacter.getRandomLowerCaseLetter()` 这种方式来访问静态函数,`getRandomLowerCaseLetter()` 这个函数被装在 `RandomCharacter` 这个小盒子中。
|
||||||
|
|
||||||
|
被访问函数所在的类
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class RandomCharacter {
|
||||||
|
/** Generate a random character between ch1 and ch2 */
|
||||||
|
public static char getRandomCharacter(char ch1, char ch2) {
|
||||||
|
return (char) (ch1 + Math.random() * (ch2 - ch1 + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Generate a random lowercase letter */
|
||||||
|
public static char getRandomLowerCaseLetter() {
|
||||||
|
return getRandomCharacter('a', 'z');
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Generate a random uppercase letter */
|
||||||
|
public static char getRandomUpperCaseLetter() {
|
||||||
|
return getRandomCharacter('A', 'Z');
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Generate a random digit character */
|
||||||
|
public static char getRandomDigitCharacter() {
|
||||||
|
return getRandomCharacter('0', '9');
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Generate a random character */
|
||||||
|
public static char getRandomCharacter() {
|
||||||
|
return getRandomCharacter('\u0000', '\uFFFF');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|||||||
@@ -0,0 +1,351 @@
|
|||||||
|
数组的定义和使用大多和C是一样的。数组是存放一类数据的一种数据结构。Java中的数组(Array)是一种特殊的对象(通过类实例化),也有特殊的语法结构。在学习Array的时候,请注意其语法,以及与后续类和对象的区别。
|
||||||
|
|
||||||
|
## 1. 声明与使用
|
||||||
|
|
||||||
|
### 1.1. 声明与使用数组
|
||||||
|
|
||||||
|
下面这个例子说明了数组的基本使用。
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class ArrayTest {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int[] myList;
|
||||||
|
|
||||||
|
myList = new int[2];
|
||||||
|
myList[0] = 0;
|
||||||
|
myList[1] = 1;
|
||||||
|
|
||||||
|
System.out.println(myList[1]);
|
||||||
|
|
||||||
|
myList = new int[3];
|
||||||
|
|
||||||
|
System.out.println(myList[1]);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Java中数组的声明与使用与C类似,`int[] myList` 定义了一个可以存放int数据类型的数组,但是此时还没有为这个数组分配内存。这一点和C的指针类是,其实myList这个变量叫做引用变量,也和指针类似。
|
||||||
|
|
||||||
|
要为myList这个数组分配内存,使用 `new int[2]` 这种类似的语法。该语法返回一个数组对象的引用地址,数组的容量是2,并赋值给引用变量 myList,然后就可以通过引用变量 myList对数组进行操作了。
|
||||||
|
|
||||||
|
可以重复对一个数组引用变量使用new语句分配内存,例如,例子中第6行和第12行。与C不同的是,Java不用对动态分配的内存进行回收。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
**特别注意这里new的语法结构,后面是数组定义时的类型,大小设置不是圆括号,而是方括号!**
|
||||||
|
|
||||||
|
### 1.2. 声明和分配内存在一行中
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class ArrayTest2 {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int[] myList = new int[2];
|
||||||
|
|
||||||
|
myList[0] = 0;
|
||||||
|
myList[1] = 1;
|
||||||
|
|
||||||
|
System.out.println(myList[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.3. 在声明的同时初始化数组
|
||||||
|
|
||||||
|
这个语法结构和C类似:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class ArrayTest3 {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int[] myList = {1,3,5,7};
|
||||||
|
System.out.println(myList[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**注意,大括号赋初值的语法只能在数组声明中使用,不能单独使用。**
|
||||||
|
|
||||||
|
### 1.4. 数组元素的缺省值
|
||||||
|
|
||||||
|
When an array is created, its elements are assigned the default value of
|
||||||
|
|
||||||
|
0 for the numeric primitive data types,
|
||||||
|
'\u0000' for char types, and
|
||||||
|
false for boolean types.
|
||||||
|
|
||||||
|
## 2. 数组操作
|
||||||
|
|
||||||
|
### 2.1. 数组对象上的操作
|
||||||
|
|
||||||
|
数组本质上是一个对象,因此直接可以在数组的引用变量上对数组进行操作。例如,取得数组的长度:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class ArrayTest2 {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int[] myList = {1,3,5,7};
|
||||||
|
System.out.println(myList.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
myList 作为一个对象,还有很多实例函数,只需要在IDE中写入这个引用变量,并在后面打一个点,就会出现这个对象的所有操作(可能包括变量、函数和常量)。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
有兴趣的可以研究一下这些函数的作用,其实从这些函数名就可以知道大约的作用。
|
||||||
|
|
||||||
|
### 2.2. 数组元素的初始值
|
||||||
|
|
||||||
|
When an array is created, its elements are assigned the default value of
|
||||||
|
|
||||||
|
0 for the numeric primitive data types,
|
||||||
|
'\u0000' for char types, and
|
||||||
|
false for boolean types.
|
||||||
|
|
||||||
|
### 2.3. 加强的for循环
|
||||||
|
|
||||||
|
和C一样,Java数组的下标也是从0开始的;结合数组的长度,可以对数组进行遍历。
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class Test {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int arrayInt[] = { 1, 3, 5, 7 };
|
||||||
|
for (int i = 0; i < arrayInt.length; i++) {
|
||||||
|
System.out.println(arrayInt[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Java还提供了一种更方便的for循环:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class ArrayTest2 {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int[] myList = { 1, 3, 5, 7 };
|
||||||
|
for (int i : myList) {
|
||||||
|
System.out.println(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
这个加强版的for循环例子如上,myList是一个数组(更准确的说是一个数据集),每次取得一个数据集的元素并保存在变量i中(注意这个临时变量i的类型必须和数组中存放数据的类型一致),直到所有的元素被遍历。
|
||||||
|
|
||||||
|
**注意,这个for循环在以后会大量用到。**
|
||||||
|
|
||||||
|
### 2.4. 数组变量是引用变量(指针)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
对数组赋值,会改变引用变量的内存指向,这和C的指针是一个概念。
|
||||||
|
|
||||||
|
**注意:Java中不存在手动回收内存,不存在指针悬空的情况。**
|
||||||
|
|
||||||
|
### 2.5. 使用函数来复制数组
|
||||||
|
|
||||||
|
可以使用循环来复制数组:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class Test {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int[] sourceArray = { 2, 3, 1, 5, 10 };
|
||||||
|
int[] targetArray = new int[sourceArray.length];
|
||||||
|
|
||||||
|
for (int i = 0; i < sourceArray.length; i++)
|
||||||
|
targetArray[i] = sourceArray[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Java在System这个类中提供了一个更加通用的数组复制函数`arraycopy`,注意这个函数是静态函数。
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class ArrayTest2 {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int[] myList1 = { 1, 3, 5, 7 };
|
||||||
|
int[] myList2 = new int[10];
|
||||||
|
System.arraycopy(myList1, 0, myList2, 0, 3);
|
||||||
|
for (int i : myList2) {
|
||||||
|
System.out.println(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
注意 System.arraycopy 这个函数的参数代表什么意思。
|
||||||
|
|
||||||
|
### 2.6. 数组作为函数参数
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class ArrayTest3 {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int[] iA = { 5, 6, 7, 8 };
|
||||||
|
System.out.println("The original array:");
|
||||||
|
printArray(iA);
|
||||||
|
|
||||||
|
changeVal(iA);
|
||||||
|
System.out.println("After change item value in function:");
|
||||||
|
printArray(iA);
|
||||||
|
|
||||||
|
changeArray(iA);
|
||||||
|
System.out.println("After change array in function:");
|
||||||
|
printArray(iA);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void printArray(int[] a) {
|
||||||
|
for (int i : a) {
|
||||||
|
System.out.println(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void changeVal(int[] a) {
|
||||||
|
for (int i = 0; i < a.length; i++) {
|
||||||
|
a[i] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void changeArray(int[] a) {
|
||||||
|
a = new int[3];
|
||||||
|
for (int i = 0; i < a.length; i++) {
|
||||||
|
a[i] = i + 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**注意:可以在函数中改变数组内部元素的值,但是无法改变数值本身的引用(例如changeArray函数),虽然数组变量是引用变量(类似指针)。**
|
||||||
|
|
||||||
|
### 2.7. 对数组元素排序
|
||||||
|
|
||||||
|
Arrys这个类中提供对数组进行排序的函数:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class Test {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
double[] numbers = { 6.0, 4.4, 1.9, 2.9, 3.4, 3.5 };
|
||||||
|
java.util.Arrays.sort(numbers);
|
||||||
|
for (double item : numbers)
|
||||||
|
System.out.print(item + " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
排序后,数组中的元素按照从小到达排列。
|
||||||
|
|
||||||
|
### 2.8. 数组元素的查找
|
||||||
|
|
||||||
|
我们可以使用循环来查找数组中某个元素的位置,其实Java已经给我们提供了一个数组查找的函数`binarySearch`。注意这里的binary是指二分法排序,而不是指二进制。如果采用二分法查找,那么数组必须是有序的。如果无法确保数组是有序的,使用前面的`java.util.Arrays.sort`函数先对数组进行排序。
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class Test {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int[] list = { 2, 4, 7, 10, 11, 45, 50, 59, 60, 66, 69, 70, 79 };
|
||||||
|
int pos = -1;
|
||||||
|
pos = java.util.Arrays.binarySearch(list, 11);
|
||||||
|
System.out.println("Index is " + pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
这个函数就是binarySearch,这个函数指使用注意这个函数的使用,前面的一窜`java.util.Arrays` 不是都指类的名字;最有最后的 `Arrays` 是类名,而 `java.util` 是命名空间。通常情况下,可以简单的理解命名空间就是目录的层级关系。
|
||||||
|
|
||||||
|
关于`java.util.Arrays`这个类还有很多其他函数,可以在IDE中通过输入点(.)查看:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
有兴趣的同学可以自己去研究一下。
|
||||||
|
|
||||||
|
### 2.9. 补充
|
||||||
|
|
||||||
|
这些内容可能考试不会直接考到,但是会方便你的编程,希望你们可以掌握。
|
||||||
|
|
||||||
|
关于Sring的操作,通常会用到把一个字符串转换成数组。例如一个以空格分隔的字符串,我们希望把每一段切取出来,形成一个数组,这时我们使用:
|
||||||
|
|
||||||
|
```java
|
||||||
|
String string = "AAA BBB CCC";
|
||||||
|
string.split(" ");
|
||||||
|
```
|
||||||
|
|
||||||
|
splite的参水是一个正则表达式(这个我们可以不用掌握),这里如果字符串是空格分隔,写入一个空格的字符串就可以了,标识拆分的字符串。
|
||||||
|
|
||||||
|
函数返回是一个 String\[\] 类型的数组,你得到的是 {"AAA", "BBB", "CCC" } ,注意,不包含分隔字符串。
|
||||||
|
|
||||||
|
相对的,可以使用 join 函数把一个字符串数组以一定的分隔符连接成一个新的字符串。
|
||||||
|
|
||||||
|
split 和 join 函数都是实例函数,必须在对象上面调用。
|
||||||
|
|
||||||
|
## 3. 读取命令行参数
|
||||||
|
|
||||||
|
细心的同学们可能注意到了,在主函数中有一个字符串的数组,这个是做什么的?其实这是传递程序运行是输入的命令行参数设计的,我们看看下面这个例子:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class Calculator {
|
||||||
|
/** Main method */
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// Check number of strings passed
|
||||||
|
if (args.length != 3) {
|
||||||
|
System.out.println("Usage: java Calculator operand1 operator operand2");
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The result of the operation
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
// Determine the operator
|
||||||
|
switch (args[1].charAt(0)) {
|
||||||
|
case '+':
|
||||||
|
result = Integer.parseInt(args[0]) + Integer.parseInt(args[2]);
|
||||||
|
break;
|
||||||
|
case '-':
|
||||||
|
result = Integer.parseInt(args[0]) - Integer.parseInt(args[2]);
|
||||||
|
break;
|
||||||
|
case '.':
|
||||||
|
result = Integer.parseInt(args[0]) * Integer.parseInt(args[2]);
|
||||||
|
break;
|
||||||
|
case '/':
|
||||||
|
result = Integer.parseInt(args[0]) / Integer.parseInt(args[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display result
|
||||||
|
System.out.println(args[0] + ' ' + args[1] + ' ' + args[2] + " = " + result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
主函数`void main(String[] args)` 中有有一个args 的字符串数组。编译这个程序,然后在命令行下执行,如果不记得命令行中如何编译和运行java,请参考第一章中的内容。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
在命令行中运行编译好的代码 `java Calculator 1 + 21` 其中 java是指虚拟机,后面的 `Calculator` 是Java编译后的可执行代码;`1 + 21` 是命令行参数。这个参数会传递给Calculator的主程序,通过main函数的args这个字符串数组解析出来。如同Scanner 对象一样,解析这个数组是按照空格区分的,因此,这个例子中我们得到的args数组是:
|
||||||
|
|
||||||
|
| 数组元素 | 值 | 说明 |
|
||||||
|
| ------- | --- | --- |
|
||||||
|
| args[0] | 1 | |
|
||||||
|
| args[1] | + | |
|
||||||
|
| args[2] | 21 | |
|
||||||
|
|
||||||
|
后面的代码就很简单了。
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 74 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 71 KiB |
Reference in New Issue
Block a user