第三章 Java基本程序设计结构


第三章 Java基本程序设计结构

3.1 一个简单的Java应用程序

public class FirstSample
{
    public static void main(String[] args)
    {
        System.out.println("We will not use 'Hello, World!"') ;
    }
}
  • Java区分大小写,main拼写成Main会报错;
  • 关键字public称为访问修饰符(第五章),用于控制程序的其他部分对这段代码的访问级别;
  • 关键字class表明Java程序中的全部内容都包含在类(第四章)中;类可以看做一个加载程序逻辑的容器,程序逻辑定义了应用程序的行为;
  • 关键字class后面紧跟类名。 Java中定义类名必须以字母开头,后面可以跟字母和数字的任意组合。长度基本上没有限制。但是不能使用Java保留字(例如,public或class) 作为类名;

标准的命名规范为(类名 FirstSample 就遵循了这个规范):类名是以大写字母开头的名词。 如果名字由多个单词组成,每个单词的第一个字母都应该大写(这种在一个单词中间使用大写字母的方式称为骆驼命名法

  • 源代码的文件名必须与公共类的名字相同,并用.java 作为扩展名。 因此,存储这段源代码的文件名必须为FirstSample.java;
  • 在编译成功之后会得到一个包含这个类字节码的文件:FirstSamlpe.class,并与源文件存储在同一目录下。然后运行这个程序:java FirstSample

运行已编译的程序时,Java 虚拟机将从指定类中的 main 方法开始执行(这里的“ 方法”就是C中所说的“ 函数”), 因此为了代码能够执行, 在类的源文件中必须包含一个 main方法。(根据Java语言规范,main方法必须声明为public)

3.2 注释

三种:

  1. // 单行
  2. / /
  3. /* / 可以用来自动生成文档

3.3 数据类型

在Java中,一共有8中基本类型,其中有4种整型、2种浮点类型、1种用于表示Unicode编码的字符单元的字符类型char和1中用于表示真值的boolean类型。

3.3.1 整型

4种整型在通常情况下,int类型最常用。但如果表示星球上的居住人数,就需要使用long类型了。byte和short类型主要用于特定的应用场合,例如,底层的文件处理或者需要控制占用存储空间量的大数组。

长整型数值有一个后缀 L 或 1 ( 如 4000000000L)。 十六进制数值有一个前缀 0x 或 0X (如OxCAFEL 八进制有一个前缀 0 , 例如, 010 对应八进制中的 8。 很显然, 八进制表示法比较容易混淆, 所以建议最好不要使用八进制常数。 0b或0B可以写二进制数,比如0b1001就是9。

另外可以位数字字面量加下划线,如1_000_000表示一百万,来让人更易读。Java编译器会去除这些下划线。

3.3.2 浮点类型

2种浮点型

double 表示这种类型的数值精度是 float 类型的两倍(有人称之为双精度数值)。绝大部分应用程序都采用 double 类型。 double 表示这种类型的数值精度是 float 类型的两倍(有人称之为双精度数值)。绝大部分应用程序都采用 double 类型。

float 类型的数值有一个后缀 F 或 f (例如, 3.14F)。没有后缀 F 的浮点数值(如 3.14 ) 默认为 double 类型。当然,也可以在浮点数值后面添加后缀 D 或 d (例如,3.14D)。

是用于表示溢出和出错情况的三个特殊的浮点数值: 正无穷大、负无穷大、NaN(不是一个数字)。

3.3.3 char类型

char 类型用于表示字符。

char 类型的字面量值要用单引号括起来。 例如: W 是编码值为 65 所对应的字符常量。它与 “A” 不同,”A” 是包含一个字符 A 的字符串, char 类型的值可以表示为十六进制值,范围为\u0000-\uffff,\u是转义字符。

特殊字符的转义序列

3.3.4 boolean类型

boolean (布尔)类型有两个值:false 和 true, 用来判定逻辑条件 整型值和布尔值之间不能进行相互转换。

3.4 变量

在 Java 中, 每个变量都有一个类型 (type)。 在声明变量时, 变量的类型位于变量名之前。

double salary;
int vacationDays;
long earthPopulation;
boolean done;

变量名必须是一个以字母开头并由字母或数字构成的序列。 变量名中所有的字符都是有意义的,并且大小写敏感。变量名的长度基本上没有限制。

3.4.1 变量初始化

声明一个变量之后,必须用赋值语句对变量进行显式初始化 。例如,Java编译器认为下面的语句是错误的:

int vacationDays;
System.out.println(vacationDays): // ERROR variable not initialized

初始化如下情况:

int a;
a = 1;

int a = 1;

在 Java 中可以将声明放在代码中的任何地方。例如,下列代码的书写形式在 Java中是完全合法的:

double salary = 65000.0;
System,out.println(salary);
int vacationDays = 12; // OK to declare a variable here

在Java中,变量的声明尽可能靠近变量第一次使用的地方,是一种良好的程序编写风格。

C和C++区分变量的声明(extern int i;)和定义(int i = 10;),Java不区分。

3.4.2 常量

在 Java 中, 利用关键字 final 指示常量。例如:

final double A = 2.45;

关键字 final 表示这个变量只能被赋值一次。 一旦被赋值之后, 就不能够再更改了。习惯上, 常量名使用全大写

在Java中,希望常量可以在一个类的多个方法中使用,这种常量称为类常量,用关键字static final设置:

public class test
{
    public static final double A = 2.45;
    public static void main(String[] args)
    {
        ...
    }
}

类常量的定义位于main方法的外部。所以在同一个类中的其它方法也可以使用这个常量。而且如果一个类常量被声明为public,那么其它类的方法也可以使用。

3.5 运算符

在 Java 中,使用算术运算符 +、-、 *、/ 表示加、减、 乘、 除运算。 当参与 / 运算的两个操作数都是整数时, 表示整数除法;否则, 表示浮点除法。 整数的求余操作(有时称为取模)用 % 表示。 例如, 15/2 等于7, 15%2 等于 1, 15.0/2 等于 7.5。

整数被 0 除将会产生一个异常, 而浮点数被 0 除将会得到无穷大或 NaN 结果。

3.5.1 数学函数与常量

在Math类中,包含了各种各样的数学函数方便调用。比如平方根Math.sqrt方法、求幂pow方法、三角函数(Math.sin、Math.cos、Math.tan、Math.atan、Math.atan2)以及以10为底的对数(Math.exp、Math.log、Math.log10),和两个用于表示π和e常量的近似值Math.PI、Math.E.

3.5.2 数值类型之间的转换

下图给出了数值类型之间的合法转换,其中实心箭头表示无信息丢失的转换;虚箭头表示可能有精度损失的转换。

两个不同类型的数值之间运算,需要转换为同一种类型:

  • 如果两个操作数中有一个是 double 类型, 另一个操作数就会转换为 double 类型。
  • 否则, 如果其中一个操作数是 float 类型, 另一个操作数将会转换为 float 类型。
  • 否则, 如果其中一个操作数是 long 类型, 另一个操作数将会转换为 long 类型。
  • 否则, 两个操作数都将被转换为 int 类型。

数值类型之间的合法转换

3.5.3 强制类型转换

即不合法的转换,会丢失精度。强制类型转换的语法格式是在圆括号中给出想要转换的目标类型,后面紧跟待转换的变量名。如:

double x = 9.997;
int nx = (int) x; // 这样nx=9,是通过截断小数部分将浮点值转换为整型

如果想对浮点数进行舍人运算, 以便得到最接近的整数(在很多情况下, 这种操作更有用), 那就需要使用 Math.round 方法:

double x = 9.997;
int nx = (int) Math.round(x);

3.5.4 结合赋值和运算符

例如:x+=4; 等价于 x=x+4;(还有*=或%=等)

如果运算符得到一个值,类型与左侧操作数不同,就会发生强制类型转换。

3.5.5 自增与自减运算符

包括“前缀”n++和“后缀”++n“两种形式。前缀形式会先完成加1;而后缀形式会使用变量原来的值。

int m = 7;
int n = 7;
int a = 2 * ++m; // now a is 16, m is 8
int b = 2 * n++; // now b is 14, n is 8

建议不要在表达式中使用++,这样的代码容易让人困惑,而且会有麻烦的bug

3.5.6 关系和boolean运算符

等于=、不等于!=、小于<、大于>、小于等于<=、大于等于>=

逻辑“与”&&、逻辑“或”||、逻辑非!

三元操作符?: ——condition ? expression1 : expression2;若条件为true ,则就为第一个表达式的值。

&& 和||运算符是按照“ 短路” 方式来求值的: 如果第一个操作数已经能够确定表达式的值,第二个操作数就不必计算了。

3.5.7 位运算符

处理整型类型时,可以直接对组成整型数值的各个位完成操作。

位运算符包括:&(“and”)、|(”or”)、^(“xor”)、~(”not”)

&和|不采用“短路”的方式来求值,即得到结果之前的两个操作数都需要计算。

另外,还有>>和<<运算符将位模式左移或右移。

int n = 1<<2; n="4" int m="1">>2; //m=0

3.5.8 括号与运算符级别

如果不使用圆括号, 就按照给出的运算符优先级次序进行计算。同一个级别的运算符按照从左到右的次序进行计算 (除了表中给出的右结合运算符外)。例如a&&b||c等价于(a&&b)||c

运算符优先级

续

3.5.9 枚举类型

枚举类型包括有限个命名的值。 例如:

enum Size {SMALL, MEDIUM, LARGE, EXTRA_LARGE};

现在,可以声明这种类型的变量:

Size s = Size.MEDIUM

Size 类型的变量只能存储这个类型声明中给定的某个枚举值, 或者 null 值,null 表示这个变量没有设置任何值。

枚举类型详细内容见第5章。

3.6 字符串

Java字符串就是Unicode字符序列。Java没有内置的字符串类型,而是在标准Java类库中提供了一个预定义类String。每个用双引号括起来的字符串都是String类的一个实例。

String a = "Hello";

3.6.1 子串

String 类的 substring 方法可以从一个较大的字符串提取出一个子串。 例如:

String greeting = "Hello";
String s = greeting.substring(0,3); // 创建了一个由字符"Hel"组成的字符串。

substring 方法的第二个参数是不想复制的第一个位置。 (0,3)即包括第0、1、2个字符。

3.6.2 拼接

Java语言允许使用+号连接两个字符串。

String expletive = "Expletive";
String PC13 = "deleted";
String message = expletive + PC13; //message = Expletivedeleted

当将一个字符串和一个非字符串的值进行拼接时,后者被转换成字符串。

int age = 13;
String rating = "PG" + age; //rating = PG13

这种特性常用于输出语句中,例如:

System.out.println("The answer is " + answer) ;

如果需要把多个字符串放在一起, 用一个定界符分隔,可以使用静态 join 方法:

String all = String.join(" / ", "S", "M", "L", "XL");// all = S / M / L / XL

3.6.3 不可变字符串

由于不能修改 Java 字符串中的字符, 所以在 Java 文档中将 String 类对象称为不可变字符串,可以修改字符串变量 greeting, 让它引用另外一个字符串, 这就如同可以将存放 3 的数值变量改成存放 4 一样。

不可变字符串的优点:编译器可以让字符串共享。

3.6.4 检测字符串是否相等

用equals方法检测两个字符串是否相等。

s.equals(t);//字符串s与t相等,则返回true,否则返回false
"Hello".equals(greeting);//s与t也可以是字符串字面量
"Hello".equalsIgnoreCase("hel1o")//不区分大小写的比较

注:不能用==来判断字符串是否相等!

3.6.5 空串与Null串

空串是一个 Java 对象, 有自己的串长度(0 ) 和内容(空)。不过,String 变量还可以存放一个特殊的值, 名为null, 这表示目前没有任何对象与该变量关联(null更多信息见第四章)。要检查一个字符串是否为null,需要一下条件:

if (str == null)

3.6.6 码点和代码单元

Java 字符串由 char 值序列组成。 char 数据类型是一个采用 UTF-16 编码表示 Unicode 码点的代码单元。大多数的常用 Unicode 字符使用一个代码单元就可以表示,而辅助字符需要一对代码单元表示。

length 方法将返回采用 UTF-16 编码表示的给定字符串所需要的代码单元数量:

String greeting = "Hello";
int n = greeting.length():// is 5

要想得到实际的长度,即码点数量,可以调用:

int cpCount = greeting.codePointCount(0, greeting.lengthQ);

3.7 输入输出

3.7.1 读取输入

要想通过控制台进行输人,首先需要构造一个 Scanner 对象,并与“ 标准输人流” System.in 关联。

Scanner in = new Scanner(System.in);

(构造函数和new操作符在第4张介绍)

nextLine方法将输入一行。使用nextLine方法是因为在输入行中可能包含空格。要想读取一个单词(以空白符作为分隔符),就调用:

String firstName = in.next();

要想读取一个整数,就调用nextInt方法:

System.out.print("How old are you? ");
int age = in.nextlnt();

Scanner类定义在java.util包中,所以要在程序开始添加上一行:import java.util.*;

从控制台读取密码,需要让输入不可见,引入Console类实现这个目的。

Console cons = System.console();
String username = cons.readLine("User name: ");
char[] passwd = cons.readPassword("Password: ");

3.7.2 格式化输出

double x = 10000.0 / 3.0;
System.out.print(x); //打印3333.33333333335

可以用8个字符的宽度和小数点后两个字符的精度打印x。即打印输出一个空格和7个字符,即3333.33。是通过调用printf方法。

System.out.printf("%8.2f", x);

在printf中,可以使用多个参数,如:

System.out.printf("\n Hello, %s. Next year, you'll be %d", name, age) ;

每一个以 %字符开始的格式说明符都用相应的参数替换。 格式说明符尾部的转换符将指示被格式化的数值类型:f 表示浮点数,s 表示字符串,d 表示十进制整数。

用于printf的转换符

另外,还可以给出控制格式化输出的各种标志。

用于printf的标志

3.7.3 文件输入与输出

对文件进行读取要一个用File对象构造一个Scanner对象:

Scanner in = new Scanner(Paths.get("myflle.txt") , "UTF-8") ;

对文件进行写入需要构造一个PrintWriter对象。在构造器中,只需要提供文件名:

PrintWriter out = new PrintWriter("myfile.txt", "UTF-8") ;

如果用一个不存在的文件构造一个 Scanner, 或者用一个不能被创建的文件名构造一个 PrintWriter,那么就会发生异常。Java 编译器认为这些异常比“ 被零除” 异常更严重。 应该告知编译器:已经知道有可能出现“输入/输出”异常。需要在main方法中用throws子句标记:

public static void main(String[] args) throws IOException
{
    Scanner in = new Scanner(Paths.get("myfi1e.txt"), "UTF-8") ;
    ...
}

3.8 控制流程

与任何程序设计语言一样, Java 使用条件语句和循环结构确定控制流程。

3.8.1 快作用域

块(即复合语句)是指由一对大括号括起来的若干条简单的 Java 语句。块确定了变量的作用域。一个块可以嵌套在另一个块中。

public static void main(String[] args)
{
    int n;
    ...
    {
    int k;
    ...
      } // k is only defined up to here
}

不能在嵌套的两个块中声明同名的变量。

3.8.2 条件语句

格式:

if (condition) statement;
if (condition) statement1 else statement2

3.8.3 循环

格式:

while (condition) statement;
do statement while (condition); //至少执行一次

3.8.4 确定循环

用程序将数字1-10打印出来:

for (int i = 1;i <= 10; i++) system.out.println(i); < code>

for语句的第1部分通常用于对计数器初始化;第2部分给出每次新一轮循环执行前要检测的循环条件;第3部分指示如何更新计数器。

3.8.5 多重选择:switch语句

例子:

Scanner in = new Scanner(System.in);
System.out.printC'Select an option (1, 2, 3, 4) ");
int choice = in.nextlnt();
switch (choice)
{
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
default:
// bad input
break;
}

文章作者: Mat Jenin
文章链接: http://matjenin.xyz
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Mat Jenin !
  目录