Java的基本程序设计结构

来源:互联网 发布:女生数据库做什么 编辑:程序博客网 时间:2024/05/17 02:19

1.一个简单的Java应用程序

Java对大小写敏感
关键字public称为访问修饰符(sccess modifier),用于控制程序的其他部分对这段代码的访问级别

public:公有的 可跨类跨包访问 (本类 本包内类 包外类)
protected:与继承有关 本类 子类可访问(相同包中的类可访问)
private:私有的 本类访问
默认模式:本类 本包可访问
final 最终的 无法改变 (不能被继承)
static 语句块用于初始化static成员变量,是最先运行的语句块(比构造方法还要先运行)

关键字class表明Java程序中的全部内容都包含在类中

将类定义为一个加载程序逻辑的容器,程序逻辑定义了应用程序的行为

标准命名规范:

类名是以大写字母开头的名词,如果有多个单词组成,每个单词的第一个字母不应该大写
源代码的文件名必须与公共类的名字相同

main方法必须声明为public

Java中的main方法必须是静态的,如果main方法正常退出,Java应用程序的退出代码为0

在Java中每个句子必须以分号结束
点号(.)用于调用方法,Java使用的通用语法是:Object.method(parameter)
对于一个方法即使没有参数也需要使用空括号

2.Java中的注释

// :注释内容从这里开始 只有一行
/* */ :注释内容在中间 可以多行
/** */: 注释内容在中间 可以多行 能够用来自动生成文档

Java中/* */ 不能嵌套使用

3.数据类型

Java是一种强语言类型,必须为么一个变量声明一种类型
8种基本类型:
整型(4种)

byte:1字节【-128~127】
short:2字节【-32768~32767】
int:4字节【-2147483648~2147483647】
long:8字节【-9223372036854775808~9223372036854775807】

长整型数值有一个后缀L,十六进制有一个前缀0x,八进制有一个前缀0,二进制有一个前缀0b
Java没有任何无符号类型

浮点型(2种)【浮点数值采用二进制系统表示,而在二进制系统中无法精确的表示分数1/10】

float:4字节【有效位数6~7位】
double:8字节【有效位数15位】

float类型的数值有一个后缀F,没有后缀F的浮点数默认为double
用于表示溢出或出错情况的3个特殊的浮点数值:

正无穷大:Double.POSITIVE_INFINITY
负无穷大:Double.NEGATIVE_INFINITY
NaN(不是数字):Double.NaN

所有非数值的值都被认为是不同的

用于表示Unicode编码的字符类型char

char【用于表示单个字符,通常表示字符常量】

特殊的转义序列符:

\b(back)退格 \u0008
\t(table)制表 \u0009
\n(next)换行 \u000a
\r(return)回车 \u000d
\”双引号 \u0022
\’单引号 \u0027
\\ 反斜杠 \u005c

!!!强烈建议不要在程序中使用char,最好将需要处理的字符串用抽象数据类型表示

所有这些转义序列符都可以出现在字符常量或者字符串的引号内
转义序列符\u还可以出现在字符常量或者字符串的引号外

用于表示真值的boolean类型

boolean
false/true

整型值和布尔值之间不能进行相互转换

4.变量

在声明变量时,变量所属的类型位于变量名之前,变量名必须是一个以字母开头的由字母或数字构成的序列,字母包括A~Z,a~z,_ , $ (或在某种语言中代表字母的任意Unicode字符);数字包括0~9(或在某种语言中代表字母的任意Unicode字符)。但是+ 空格 不能出现在变量名中【变量名中所有的字符都是有有意义的,并且大小写敏感,变量的长度没有限制】

$ 不提倡使用这个字符
逐一声明每一个变量可以提高程序的可读性
声明一个变量之后,必须用赋值语句对变量进行显式初始化【千万不要使用未初始化的变量】
变量的声明尽可能地靠近第一次使用的地方

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

类常量 (static final 关键字)
在Java中,经常希望某个常量可以在一个类中的多个方法中使用,这样的常量称为类常量
类常量的定义在main方法之外【如果一个常量被声明为public 那么其他类的方法也可以使用这个常量】

5.运算符

当参与/运算的2个操作数都是整数时,表示整数除法;否则表示浮点数除法
整数被0除将会产生一个异常,浮点数被0除将会得到无穷大或NaN结果

【默认情况下运行中间计算结果采用扩展的精度(如intel处理器的中间结果是存放在80位的寄存器中),但是使用strictfp关键字标记的方法或者类必须使用严格的浮点计算来产生理想的结果】

1.自增自减运算符

因为这些运算符改变了变量的值,所以它的操作数不能是数值(例如4++是一条非法语句)
前缀方式先进行加1运算,后缀方式则使用变量原来的值

2.关系运算符与boolean运算符

&&逻辑与(一假必假)
||逻辑或(一真必真)
!逻辑非
三元操作符 condition?expression1 :expression2 (当condition为真,计算expression1 ,否则计算expression2)

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

3.位运算符

&(与)一假必假
|(或)一真必真
^(异或)同0异1

&和|应用于布尔值,得到的结果也是布尔值;不采用短路的方式,在得到计算结果前,一定要计算2个操作数的值

4.左移(<<)右移(>>)

>>>(高位用0填充)
>>(高位用符号位填充)
没有<<<运算符

对位移运算符右侧的参数需要进行模32的运算
若左侧的操作数是long类型,需要对右侧的操作数模64

5.数学函数与常量
Math类中的sqrt方法处理的不是对象,这样的方法称为静态方法
Math提供的三角函数:

Math.sin
Math.cos
Math.tan
Math.atan
Math.atan2

Math提供的指数函数:

Math.exp(例Math.exp(a)—>e的a次方)
Math.log
Math.log10

Math提供的常量:

Math.PI
Math.E

【静态导入:import static java.lang.Math.*;这样的话不必在数学方法名和常量名前添加前缀“Math.”】

6.数值类型之间的转换
【无信息丢失】

byte——short——int——long
char——int——double
float——double

【可能有精度损失】

int—float
long—float
long—double

当2个操作数的类型不同时,先要将2个操作数转换为同一个类型,然后进行计算

if2个中有一个是double){    把另一个转换为double;}else{    if2个中有一个是float)    {        把另一个转换为float;    }    else{        if2个中有一个是long)        {            把另一个转换为long;        }        else{            把2个转换为int;            }        }    }

7.强制类型转换
强制类型转换的语法格式是在圆括号中给出想要转换的目标类型,例如:

double x = 9.9;int nx = (int)x;

【强制类型转换通过截断小数部分将浮点值转换为整型】

如果想要将浮点数进行舍入运算,以便取得最接近的整数,需要使用Math.round方法,例如:

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

【当调用round方法的时候,仍然需要进行强制类型转换,因为round方法返回的结果是long类型】

只有极少数情况需要将boolean类型转换为数值类型,这是可以使用三元运算符 boolean?1:0

不确定优先级的时候使用括号括起来是个不错的选择

8.枚举类型
枚举类型包括有线个命名的值

enum Size {SMALL,MEDIUM,LARGE,EXTRA_LARGE}

声明变量:
枚举名 变量名 = 枚举名.枚举值

Size s = Size.MEDIUM;

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

6.字符串

Java字符串就是Unicode字符序列,Java没有内置的字符串类型,每个双引号括起来的字符串都是String类的一个实例

子串

String greeting = "Hello";String s = greeting.substring(0.3);

substring方法的第2个参数是不想复制的第一个位置,这样容易计算字符串的长度,第2个参数减第1个参数

拼接

“+”连接(拼接)两个字符串
当一个字符串和一个非字符串的值进行拼接时,后者被转换成字符串(任何一个Java对象都可以转换成字符串)

不可变字符串

String类没有提供用于修改字符串的方法,由于不能修改Java字符串中的字符,所以Java文档中将String类对象成为不可变字符串
可以修改字符串变量,如greeting,让它引用另一个字符串
【不可变字符串的优点:编译器可以让字符串共享(字符串放在堆中,如果没有变量引用它,Java将自动的进行垃圾回收)】

检测字符串是否相等

使用equals方法检测两个字符串是否相等(区分大小写)

s.equals(t);

如果相等返回true,否则返回false,s和t可以是字符串变量,也可以是字符串常量

"Hello".equalsIgnoreCase("hello");//不区分大小写

一定不能使用==运算符检测2个字符串是否相等,这个运算符只能够确定2个字符串是否放置在同一个位置上
如果虚拟机始终将相等的字符串共享,就可以使用==运算符检测是否相等,但实际上只有字符串常量是共享的,而+或者substring等操作产生的结果并不是共享的

空串和Null串

空串“”是长度为0的字符串,空串上一个Java对象,有自己的串长度(0)和串内容(空)
null表示目前没有任何对象与该变量关联(首先要判断字符串是否为null)

代码点与代码单元

char数据类型是一个采用UTF-16编码表示Unicode代码点的代码单元,大多数常用的Unicode字符使用一个代码单元,辅助字符使用一对代码单元。

length方法返回的是给定字符串的代码单元数量
想要得到实际的长度(即代码点的数量)调用codePointCount方法

Java对字符串中的代码单元和代码点从0开始计数

构建字符串

有时候需要由较短的字符串构建字符串,例如,按键或来自文件中的单词,采用字符串连接的方式达到此目的的效率比较低,每次连接字符串,都会构建一个新的String对象,耗时浪费空间,使用StringBuilder类就可以避免这个问题。
StringBuilder bulider = new StringBuilder();bulider.append(ch);//添加一个字符bulider.append(str);//添加一个字符串String completedString = bulider.toString();

7.输入输出

现代的程序都使用GUI收集用户的输入

读取输入

首先构造一个Scanner对象,并与标准输入流“System.in”关联
使用nextLine方法是因为在输入行中可能包含空格

Scanner in = new Scanner(System.in);String name = in.netxLine();

想要读取一个整数就用nextInt方法
想要读取一个浮点数就用nextDouble方法

当使用的类不是定义在基本java.lang包中时,一定要使用import指示字将相应的包加载进来
因为输入是可见的,所以Scanner类不适合用于从控制台读取密码,引入Console类实现这个目的

Console cons = System.console();String unsername = cons.readLine("User Name:");Char[] passwd = cons.readPassword("Password:");

为了安全起见,返回的密码存放在一维字符串数组中,而不是字符串中,对密码进行处理后,应该马上用一个填充值覆盖数组元素
采用Console对象处理输入不如采用Scanner方便,每次只能读取一行输入,而没有能够读取一个单词或一个数值的方法

格式化输出

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

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

书本 p56-p60

文件输入与输出

想要对文件进行读取,就需要一个用File对象构造一个Scanner对象,如下:

Scanner in = new Scanner(Paths.get("myfile.txt"));

如果文件名中包含反斜杠,就要记住在每个反斜杠之前加一个额外的反斜杠
可以构造一个带有字符串参数的Scanner,但是这个Scanner将字符串结束为数据,而不是一个文件名:

Scanner in = new Scanner("myfile.txt");//error

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

PrintWtiter out = new PrintWriter("myfile.txt");

如果用一个不存在的文件构造一个Scanner,或者用一个不能被创建的文件名构建一个PrintWriter,那么会发生异常

8.控制流程

块是指一对花括号括起来的若干条简单的Java语句,块确定了变量的作用域
不能再嵌套的2个块中声明同名的变量

条件:if(condition)statement
循环:while(condition)statement【如果开始循环的条件为false,则while循环体一次也不执行】
循环:do statement while(condition)先执行语句在检测循环条件然后重复语句在检测循环条件以此类推
确定循环:for(计数器初始化;新一轮循环执行前要检测的循环条件;指示如何更新计数器)【for语句的3个部分应该对同一个计数器进行初始化,检测和更新】
多重选择:switch(choice){case 1:… break;case 2:… break;… default:break}

在循环中检测2个浮点数是否相等需要格外小心,有可能永远无法相等

for语句的第1部分声明了一个变量之后,这个变量的作用域就为for循环的整个循环体,如果在for循环内部定义了一个变量,这个变量不能再循环体之外使用,可以在各自独立的不同循环中定义同名的变量

switch语句中编译代码时可以考虑加上-Xlint:fallthrough选项(如 javac -Xlint:fallthrough Test.java)这样一来,如果某个分支最后缺少一个break语句,编译器就会给出一个警告
switch语句中,case标签可以是char byte short int的常量表达式,还可以是枚举常量,字符串字面量(当在switch语句中使用枚举常量时,不必在每个标签中指明枚举名,可以有switch的表达式值确定)

中断控制流程语句

循环的跳出(break continue return)

break :跳出所在的switch或循环(跳出循环不论循环条件是否结束,循环都结束) 【只能跳出语句块,不能跳入语句块】
continue :结束本次循环,进入下一次循环(不论continue后面是否有代码都结束本次循环) 【将控制转移到最内层循环的首部】
return : 离开语句所在方法

Java还提供一种带标签的break语句,用于跳出多重嵌套的循环语句,标签必须放在希望跳出的最外层循环之前,并且必须紧跟一个冒号

还有一种带标签的continue语句,将跳转到与标签匹配的循环首部

事实上,可以将标签应用到任何语句中,甚至可以应用到if语句或者块语句中

label:{. . .if(condition)break label;//exits block. . .}//jumps here when the break statement executes

如果将continue语句用在for循环中,就可以跳到for循环的“更新”部分

9.大数值

如果基本的整数和浮点数精度不能满足需求,那么可以使用java.math包中的2个很有用的类:BigInteger和BigDecimal。这2个类可以处理包含任意长度数字序列的数值。

BigInteger类实现了任意精度的整数运算
BigDecimal类实现了任意精度的浮点数运算

使用静态的valueOf方法可以将普通的数值转换为大数值:

BigInteger a = BigInteger.valueOf(100);

遗憾的是不能使用我们熟悉的算术运算符(如+ *)处理大数值,需要使用大数值类中的add和multiply方法:

BigInteger c = a.add(b);//c=a+bBigInteger d = c.multiply(b.add(BigInteger.valueOf(2)));d=c*(b+2)

Java没有提供运算符重载功能
要想计算大数值浮点数的商,必须给出舍入方式(rounding mode) RoundingMode.HALF_UP(四舍五入)

10.数组

数组是一种数据结构,用来存储同一类型值的集合,通过整型下标可以访问数组中的每一个值
在声明数组变量时,需要指出数组类型(数组元素类型紧跟[ ])和数组变量的名字:

int[ ] a;//只声明了变量a,并没有将a初始化为一个真正的数组

数组长度不要求是常量
创建一个数字数组时,所有的元素都初始化为0,boolean数组的元素会初始化为false,对象数组的元素则初始化为一个特殊值null;一旦创建了数组,就不能再改变它的大小

for each 循环

forvariable:collection)statement

定义一个变量用于暂存集合汇总的每一个元素,并执行相应的语句,collection这一集合表达式必须是一个数组或者是一个实现了Iterable 接口的类对象
for each 循环语句的循环变量将会遍历数组中的每个元素,而不需要使用下标值

有一个更简单的方式打印数值中的所有值,Arrays.toString(a),返回一个包含数组元素的字符串,这些元素被放置在括号内,用逗号分隔,如“[2,3,4,5,11,13]”

数组初始化以及匿名数组
在Java中,允许数组长度为0,数组长度位0和null不同。

数组拷贝
在Java中允许将一个数组变量拷贝给另一个数组变量,这时2个变量引用同一个数组

luckNumbers = Arrays.copyOf(luckNumbers,2*luckNumbers.length);

这个方法用于增加数组的大小,如果数组元素是整型,多余元素都初始化为0,如果数组元素是boolean型,多余元素都初始化为false,如果长度长度小于原始数组的长度,则只是拷贝最前面的数据元素。

命令行参数
每一个Java应用程序都有一个带有String arg[ ]参数的main方法,这个参数表明main方法将接收一个字符串数组,也就是命令行参数,参数以空格分隔

数组排序
想要对数值型数组排序,使用Arrays类的sort方法(这个方法使用优化的快速排序算法)

int[ ] a = new int[1000];. . .Arrays.sort(a);

Math.random方法返回一个[0,1)的随机浮点数
使用equals比较两个数组是否相等:如果2个数组大小相同,并且下标相同的元素对应相等,返回true

多维数组
for each循环不能自动处理二维数组的每一个元素,它按照行,也就是一维数组处理的
想要快速打印一个二维数组的数据元素列表,可以调用:

System.out.println(Arrays.deepToString(a));

不规则数组
Java实际上没有多维数组,只有一维数组,多维数组被解释为“数组的数组”

0 0