一、基本语法
下面是一个最简单的 Java 应用程序,它只发送一条消息到控制台窗口中。
public class FirstSample{
public static void main(String[] args){
System.out.println("Hello World!");
}
}
接下来,根据上面的代码示例,简单说一下 Java 的基本语法。
1.1 Java 对大小写敏感
1.2 访问修饰符(access modifier)
用于控制程序的其他部分对这段代码的访问级别。
下面归纳一下 Java 用于控制可见性的 4 个访问修饰符
- private:仅对本类可见
- public:对所有类可见
- protected:对本包和所有子类可见
- 默认(无修饰符):对本包可见
1.3 class 关键字
表明 Java 程序中的全部内容都包含在类中。可以把类看成是一个加载程序逻辑的容器。
1.4 类名
- 关键字 class 后面紧跟类名。类名必须以字母开头,后面可以跟字母和数字的任意组合。长度基本上没有限制。不能使用 Java 保留字作为类名。
- 标准的类命名规范为:
- 以大写字母开头的名词
- 如果有多个单词组成,每个单词的第一个字母都应该大写。这种命名方式称为骆驼命名法
- 源文件的文件名必须与公共类的类名相同,并用 .java 作为扩展名
1.5 main 方法
运行编译程序时,Java 虚拟机将从指定类中的 main 方法开始执行,每个 Java 应用程序都必须有一个 main 方法。根据 Java 语言规范,main 方法必须声明为 public。Java 中的 main 方法必须是静态的(static)。
1.6 源代码中的括号 {}
花括号用来划分程序的各个部分(通常称为块)。Java 中任何方法的代码都用 “{” 开始,用 “}” 结束。
1.7 关键字 void 表示这个方法没有返回值
1.8 在 Java 中,每个句子必须使用分号结束。(特殊说明:回车不是语句的结束标志,因此可以将一条语句写在多行上)
1.9 System.out 对象的 println 方法用来打印信息到控制台
1.10 点号 (.) 用于调用方法。Java使用的通用语法是:
object.method(parameters)
在 Java 的方法中,可以没有参数,也可以有一个或多个参数。对于一个方法,即使没有参数也需要使用空括号。
二、注释
在 Java 中,有三种书写注释的方式:
- 最常用的方式是使用
//
,其注释内容充开始到本行结束 - 当需要长篇注释时,可以使用
/*
和*/
将一段比较长的注释括起来 - 第三种注释可以用来自动生成文档。这种注释以
/**
开始,以*/
结束
三、数据类型
Java 是一种强类型语言。这就意味着必须为每一个变量声明一种类型。
在 Java 中,一共有 8 种基本类型(primitive type),其中有 4 种整型、2 种浮点类型、1 种用于表示 Unicode 编码的字符单元的字符类型、1 种表示真值的 boolean 类型。
3.1 整型
整型用于表示没有小数部分的数组,它允许是负数。Java 提供了 4 种整型。
类型 | 存储需求 | 取值范围 |
---|---|---|
int | 4 字节 | -2 147 483 648 ~ 2 147 483 647 |
short | 2 字节 | -32 768 ~ 32 767 |
long | 8 字节 | -9 223 372 036 854 775 808 ~ 9 223 372 036 854 775 807 |
byte | 1 字节 | -128 ~ 127 |
“在 Java 中,整型的范围与运行 Java 代码的机器无关。这就解决了软件从一个平台移植到另一个平台,或者在同一个平台中不同操作系统之间进行移植给程序员带来的诸多问题。由于 Java 程序必须保证在所有机器上都能得到相同的运行结果,所以每一种数据类型的取值范围必须固定。” —— 《Java 核心技术 卷I》
3.2 浮点类型
浮点类型用于表示有小数部分的数组。在 Java 中有两种浮点类型。
类型 | 存储需求 | 取值范围 |
---|---|---|
float | 4 字节 | 大约 ±3.402 823 47E + 38F(有效位数为 6 ~ 7 位) |
double | 8 字节 | 大约 ±1.797 693 134 862 315 70E + 308(有效位数为 15 位) |
- double 表示这种类型的数值精度是 float 类型的两倍(有人称之为双精度数值)
- float 类型的数值有一个后缀 F (例如,3.14F)。没有后缀 F 的浮点数值(如 3.14)默认为 double 类型。也可以在浮点数值得后面添加后缀 D (例如,3,14D)
所有的浮点数值计算都遵循 IEEE 754 规范。下面是用于表示溢出和出错情况的三个特殊浮点数值:
- 正无穷大
- 负无穷大
- NaN (不是一个数字)
例如,一个正整数除以 0 的结果为正无穷大。计算 0/0 或者负数的平方根结果为 NaN。
常量 Double.PROSITIVE_INFINITY、Double.NEGATIVE_INFINITY、Double.NaN 分别表示这三个特殊的值。(Float类型的常量同理)
特别说明,不能这样坚持一个特定值是否等于 Double.NaN:
if(x == Double.NaN) // is never true
//所有 “非数值” 的值都认为是不相同的。然而,可以使用 Double.isNaN 方法:
if(Double.isNaN(x)) // check whether x is "not a number"
3.3 char 类型
char 类型用于表示单个字符。通常用来表示字符常量。
3.4 boolean 类型
boolean(布尔)类型有两个值:false 和 true,用来判断逻辑条件。整型值和布尔值之间不能进行互相转换。
四、变量
4.1 声明变量
在 Java 中,每一个变量属于一种类型(type)。在声明变量时,变量所属的类型位于变量名之前。
变量名必须是一个字母开头的由字母和数字构成的序列。
变量名中所有的字符都是有意义的,并且大小写敏感。变量名的长度没有限制。
不能将变量名命名为 Java 保留字。
可以在一行中声明多个变量:
int i,j;
不提倡使用这种风格。逐一声明每一个变量可以提高程序的可读性。
变量初始化
声明一个变量之后,必须用赋值语句对变量进行显式初始化,不能使用未被初始化的变量。
初始化语法:
int i = 10;//声明一个 int 类型的变量,变量名为 i,初始化为 10。
常量
在 Java 中,使用 final 关键字指示变量。例如:
final int SIZE = 10;
关键字 final 表示这个变量只能被赋值一次。一旦被赋值之后,就不能够再更改了。常量名推荐使用全大写。
如果某个常量在一个类中的多个方法中使用。通常将这些变量称为类常量。可以使用 static final 设置一个类常量。例如:
public static final int COUNT = 10;
五、运算符
Java中,使用算术运算符 +
、-
、*
、/
表示加、减、乘、除运算。求余操作(取模)用 %
表示。
通常,将运算符放在赋值号 =
的左侧,如 *=
或 %=
。
5.1 自增运算符与自减运算符
对数值常量加 1 、减 1 的操作,可以使用自增运算符和自减运算符。
方式一:
- n++
- n--
方式二:
- ++n
- --n
两种方式都是对变量值加1。区别是:方式一使用变量原来的值;方式二先进行加 1 运算。
注意,操作数不能是数值。例如:4++ 就是一条非法的语句
代码示例:
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
5.2 关系运算符与 boolean 运算符
==
: 检测是否相等!=
: 检测是否不相等<
:小于>
:大于<=
:小于等于>=
:大于等于&&
:逻辑 “与”||
:逻辑 “或”!
:逻辑 “非”
注意: &&
和 ||
是按照 “短路” 方式求值得。如果第一个操作数已经能够确定表达式的值,第二个操作数就不必计算了。比如说:
expression1 && expression2
如果第一个表达式的值为 false,结果不可能为真。因此,第二个表达式就没必要计算了。
expression1 || expression2
如果第一个表达式的值为 true,结果自动为 true,不必计算第二个表达式。
5.3 三元运算符
表达式:condition ? expression1:expression2
当条件 condition 为真时计算第一个表达式,否则计算第二个。例如:
x < y ? x : y
返回 x 和 y 中较小的那个值。
5.4 位运算符
在处理整型数值时,可以直接对组成整型数值的各个位进行操作。位运算符包括:
&("与")、|("或")、^("异或")、~("非")
另外,>>
和 <<
运算符将二进制进行右移或左移操作。
最后,>>>
运算符将用 0 填充高位;>>
运算符用符号填充高位。没有 <<<
运算符。
5.5 数学函数和数学常量
数学函数
在 Math 类中,包含了各种各样的数学函数。
- Math.sqrt(x):计算数值 x 的平方根
- Math.pow(x,a):计算 x 的 a 次幂
Math 类提供一些常用的三角函数:
- Math.sin
- Math.cos
- Math.tan
- Math.atan
- Math.atan2
指数函数以及它的反函数——自然对数以及以 10 位底的对数
- Math.exp
- Math.log
- Math.log10
数学常量
Java 提供了两个用于表示 π 和 e 的近似值:
- Math.PI
- Math.E
5.6 数值类型之间的转换
在程序运行时,需要将一种数值类型转为另一种数值类型。下图给出了数值类型之间的合法转换
图中六个黑色箭头,表示无信息丢失的转换;三个红色箭头,表示可能有精度损失的转换。
5.7 强制类型转换
比如说,两个操作数中一个是 int 类型,一个是 double 类型,这时,int 类型的值将会自动地转换为 double 类型。我们称之为自动类型转换。
但有的时候,需要将 double 转换成 int,这种情况下,需要通过强制类型转换实现这个操作。
强制类型转换的语法是在圆括号中给出想要转换的目标类型,后面紧跟着待转换的变量名。例如:
double x = 9.997;
int i = (int) x;
这时,变量 i 的值为 9 。你可能有疑问,为什么不是 10 呢?因为强制类型转换通过截断小数部分将浮点值转换成整型,并没有进行舎入运算。
如果想对浮点数进行舎入运算,以便得到最接近的整数,可以使用 Math.round 方法:
double x = 9.997;
int i = (int)Math.round(x);
5.8 枚举类型
有时候,变量的取值只在一个有限的集合内。例如,销售的服装只有小、中、大、超大这四种尺寸。当然,可以将这些尺寸分别编码为 1、2、3、4 或者 S、M、L、X。但这样存在着一定的隐患。在变量中很可能保存的是一个错误的值(如 0 或 m)。
这里只简单说明一下为什么使用枚举,具体内容以后再单独写篇博客介绍。
六、字符串
Java 字符串就是 Unicode 字符序列。Java 没有内置的字符串类型,而是在标准 Java 类库中提供了一个预定义类,名为 String。每一个使用双引号括起来的字符串都是 String 类的一个实例。例如:
String e = "";// an empty string
String greeting = "Hello";
6.1 子串
String 类的 substring 方法可以从一个较大的字符串中提取一个子串。例如:
substring 方法的第一个参数代表起始位置,第二个参数是 不想复制的第一个位置。上图代码中,从 0 开始复制,直到 3 为止,但不包含 3。
6.2 拼接
Java 语言允许使用 + 号拼接两个字符串。
当将一个字符串和一个非字符串的值进行拼接时,后者被转换成字符串(任何一个 Java 对象都可以转换成字符串)。
6.3 不可变字符串
String 类对象称为不可变字符串
一旦创建 String 类对象,就不能修改它的值。对于已经存在的 String 对象的修改,都是重新创建一个新的对象,然后再赋予新的值。
例如:
String s = “a”;
s = "b";
String s = "a" 是一个对象,s = “b” 是另一个对象,第一个对象会被垃圾回收。
String 是 final 类,即不能被继承。作为参数传递时,只是复制了一份引用。
不可变字符串的优点
编译器可以让字符串共享。
可以想象将各种字符串存放在公共的存储池中。字符串变量指向存储池中相应的位置。如果复制一个字符串变量,原始字符串与复制的字符串共享相同的字符。
6.4 检测字符串是否相等
使用 equals 方法检测两个字符串是否相等。
使用 equalsIgnoreCase 方法检测两个字符串是否相等,且不区分大小写。
注意: 一定不能使用 ==
运算符检测两个字符串是否相等!因为 ==
运算符只能比较两个字符串
是否放置在同一个位置上。
只有字符串常量是共享的,而 +
或 substring
等操作产生的结果并不是共享的
6.5 空串与 Null串
空串 ""
是长度为0的字符串。可以调用 length 方法检测字符串是否为空。
空串是一个 Java 对象,有自己的串长度(0)和内容(空)。String 变量还可以存放一个特殊的值,名为 null,这表示目前还没有任何对象和该变量关联。
如果要判断一个字符串既不是 null 也不是 空串,可以使用下面方法:
if(str != null && str.lengh() != 0)
注意:首先要检查 str 不为 null,再检查是否为空串。因为在一个 null 值上调用方法,程序会报异常。
6.6 构建字符串
想象一下,按键的时候,如果采用字符串连接的方式,每次连接字符串,都会构建一个新的 String 对象,即耗时,又浪费空间。
使用 StringBuilder 类就可以避免这个问题。
当每次需要添加一部分内容时,就调用 append 方法。
在需要构建字符串时就调用 toString 方法就可以得到一个 String 对象。
StringBuilder 和 StringBuffer
在 JDK5.0 中引入 StringBuilder 类。它的前身是 StringBuffer。StringBuffer的效率稍微有些低,但允许采用多线程的方式执行添加或删除字符的操作。如果所有字符串在一个单线程中编辑,则应该使用 StringBuilder。