03-Java程序的构成
前言
与所以的语言一样,Java也是由语言规范(Java Specification)和API(Application Programming Interface,应用程序编程接口)组成的。
Java语言主要由标识符、关键字、分隔符、数据类型、运算符、表达式、语句、方法、类、包等元素组成。
注意:一个 Java 程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作。 下面简要介绍下类、对象、方法和实例变量的概念。
包(package): 包用来分类存放类和接口,相当于文件夹的概念
类(class): 类是一个模板,它描述一类对象的行为和状态。
接口(interface): 接口是实现多继承的途径,是常量和抽象方法的结合体。
对象: 对象是类的一个实例,有状态和行为。例如,一条狗是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等。
方法: 方法就是行为,一个类可以有很多方法。逻辑运算、数据修改以及所有动作都是在方法中完成的。
实例变量: 每个对象都有独特的实例变量,对象的状态由这些实例变量的值决定。
一、标识符(Identifier)
用一些符号来标识一些名称,如包(package)、类(class)、接口(interface)、对象(object)、方法(method)、成员变量(field)、局部变量(local variable)、常量(constant) 等,这些符号被称为标识符。
Java标识符在命名时应尽量体现各自描述的事务的属性、功能等。
Java标识符命名规则
(1)标识符由字母(a-z、A-Z)、数字(0~9)、下划线(_)以及美元符($)混合组成,并且不能以数字开头。
(2)不能用Java的关键字保留字做标识符。
(3)Java标识符严格区分大小写。
(4)出于对兼容性的考虑,标识符中不要出现汉字。
Java中命名约定
(1)尽量使用完整的英文单词或通用性的英文缩写,能见词知意。
(2)词组中采用大小写混合,使之更易于辨别。
(3)避免使用过长的标识符,一般控制在十五个字符以内。
Java中命名惯例
(1)包名应为名词或者名词性短语,全部小写。
(2)类名、接口名应为名词或者名词性短语,各单词首字母大写。
(3)方法名应为动词或者动词性短语,首个单词的首字母小写,其余各单词的首字母大写。
(4)变量名应为名词或者名词性短语,首个单词的首字母小写,其余各单词的首字母大写。
(5)常量名全大写。
二、关键字(KeyWord)或保留字(Reserved Word)
关键字(KeyWord) 是Java语言本身使用的系统标识符,全部采用小写字母,有特定的语法含义,不能用做标识符。
保留字(Reserved Word) 是其他语言已经定义过的字,一些保留字可能没有相对应的语法,考虑到扩展性,为了向后兼容不能再将其作为变量名。const和goto是java的保留字。
访问权限修饰符 | public | protected | private | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
类,方法和变量修饰符 | abstract | final | class | enum | interface | extends | implements | new | static | strictfp | synchronized | transient | volatile | native |
程序控制 | if | else | switch | case | default | for | while | do | break | continue | return | |||
异常处理 | try | catch | finally | throw | throws | |||||||||
包控制 | import | package | ||||||||||||
基本数据类型 | byte | short | int | long | float | double | char | boolean | void | |||||
返回值类型 | null | true | false | |||||||||||
引用类型变量 | super | this | instanceof | |||||||||||
保留字 | goto | const |
1.访问权限修饰符
public 公共的
public 关键字是可以应用于类、方法或属性(在类中声明的变量)的访问控制修饰符。使一个类、方法或属性可以被任何位置的方法访问,权限最大。
protected 受保护的
public 关键字是可以应用于类、方法或属性(在类中声明的变量)的访问控制修饰符。使一个类、方法或属性只能被同一个包中的类或该类的子类访问。
默认的(default)
当没有修饰符时默认此权限,也是可以应用于类、方法或属性(在类中声明的变量)的,使一个类、方法或属性只能被同一个包中的类访问,该类的子类也不能访问。
private 私有的
public 关键字是可以应用于类、方法或属性(在类中声明的变量)的访问控制修饰符。使一个方法或属性只能被本类访问。其他类均不可访问。
注意:
1、可以使用get()、set()方法对私有化属性进行访问、修改。
2、私有是封装的一种表现形式,封装不是私有,封装包含私有。
权限一览表
访问权限 | 当前类 | 包 | 子类 | 其他包 |
---|---|---|---|---|
public | ∨ | ∨ | ∨ | ∨ |
protect | ∨ | ∨ | ∨ | × |
default | ∨ | ∨ | × | × |
private | ∨ | × | × | × |
2.类方法、变量、修饰符
abstract 声明抽象
abstract关键字可以修改类或方法。
abstract修饰的类为抽象类,不能被实例化,但是可以扩展(增加子类)。
abstract修饰的方法为抽象方法(只有方法的声明,没有方法的实现),不在声明它的类中实现,但必须在某个子类中重写。
final 最终、不可改变
在Java中,final关键字可以用来修饰类、方法和变量(包括成员变量和局部变量)。final方法在编译阶段绑定,称为静态绑定(static binding)。
1、修饰类
当用final修饰一个类时,表明这个类不能被继承,不能有子类。也就是说,如果一个类你永远不会让他被继承,就可以用final进行修饰。final类中的成员变量可以根据需要设为final,但是要注意final类中的所有成员方法都会被隐式地指定为final方法。
2、修饰方法
使用final方法的原因有两个。
第一个原因是把方法锁定,以防任何继承类修改它的含义。
第二个原因是效率。
在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升。在最近的Java版本中,不需要使用final方法进行这些优化了。
因此,如果只有在想明确禁止该方法在子类中被覆盖的情况下才将方法设置为final的。
还有就是,类的private方法会隐式地被指定为final方法。
3、修饰变量
修饰变量是final用得最多的地方。
对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。引用变量被final修饰之后,虽然不能再指向其他对象,但是它指向的对象的内容是可变的。
4、final参数
当函数参数为final类型时,你可以读取使用该参数,但是无法改变该参数的值或者引用指向。
总结:
final修饰类时该类不能被继承。
final修饰方法时该方法不能被重写。
final修饰变量时该变量为常量。
class 类
class 关键字用来声明新的 Java 类,该类是相关变量或方法的集合。
(1) 类是面向对象的程序设计方法的基本构造单位。
(2) 类通常代表某种实际实体,如几何形状或人。
(3) 类是对象的模板。
(4) 每个对象都是类的一个实例。
(5) 要使用类,通常使用 new 操作符将类的对象实例化,然后调用类的方法来访问类的功能。
enum 枚举
enum关键字用来声明一个枚举,各个常量使用逗号’,’ 来分割。
Java 枚举是一个特殊的类,一般表示一组常量,比如一年的 4 个季节,一个年的 12 个月份,一个星期的 7 天,方向有东、南、西、北等。
interface 接口
interface 关键字用来声明新的 Java 接口,接口是方法的集合。
接口是 Java 语言的一项强大功能。任何类都可声明它实现一个或多个接口,这意味着它实现了在这些接口中所定义的所有方法。
实现了接口的任何类都必须提供在该接口中的所有方法的实现。一个类可以实现多个接口。
extends 继承
extends 关键字用在对 class 或 interface 使用的类或接口的声明中,用于指示所声明的类或接口是其名称后跟有 extends 关键字的类或接口的子类。
子类继承父类的所有 public 和 protected 变量和方法(但是不包括构造函数)。
子类可以重写父类的任何非 final 方法。一个类只能扩展一个其他类(即Java只允许单继承)。
implements 实现
implements 关键字用在对 class 使用的类的声明中使用,以指示所声明的类提供了在 implements 关键字后面的名称所指定的接口中所声明的所有方法的实现。
类必须提供在接口中所声明的所有方法的实现。
一个类可以实现多个接口。
new 新,创建
new 关键字用于创建类的新实例。
new 关键字后面的参数必须是类名,并且类名的后面必须是一组构造方法参数(必须带括号)。
参数集合必须与类的构造方法的名称相匹配。
注意:= 赋值号左侧的变量的类型必须与要实例化的类或接口具有赋值兼容关系。左侧声明的变量为引用型变量。
static 静态
static可以用于修饰属性,可以修饰代码块,也可以用于修饰方法,还可以用于修饰类。
static修饰属性: 无论一个类生成了多少个对象,所有这些对象共同使用唯一一份静态的成员变量;一个对象对该静态成员变量进行了修改,其他对象的该静态成员变量的值也会随之发生变化。如果一个成员变量是static的,那么我们可以通过 ‘类名.成员变量名’ 的方式来使用它。
static修饰方法: static修饰的方法叫做静态方法。对于静态方法来说,可以使用 ‘类名.方法名’ 的方式来访问。静态方法只能继承,不能重写(Override),因为重写是用于表现多态的,重写只能适用于实例方法,而静态方法是可以不生成实例直接用类名来调用,这就会与重写的定义所冲突,与多态所冲突,所以静态方法不能重写,只能是隐藏。
注意:static方法与非static方法的调用
1.不能在静态方法中访问非静态成员变量。
2.可以在静态方法中访问静态的成员变量。
3.可以在非静态方法中访问静态的成员变量:因为静态方法可以直接用类名来调用,而非静态成员变量是在创建对象实例时才为变量分配内存和初始化变量值。
4.不能在静态方法中使用this关键字:因为静态方法可以直接用类名来调用,而this实际上是创建实例时,实例对应的一个应用,所以不能在静态方法上使用this。
static修饰代码块: 静态代码块。静态代码块的作用也是完成一些初始化工作。首先执行静态代码块,然后执行构造方法。静态代码块在类被加载的时候执行,而构造方法是在生成对象的时候执行;要想调用某个类来生成对象,首先需要将类加载到Java虚拟机上(JVM),然后由JVM加载这个类来生成对象。
注意:
1.类的静态代码块只会执行一次,是在类被加载的时候执行的,因为每个类只会被加载一次,所以静态代码块也只会被执行一次。
2.而构造方法则不然,每次生成一个对象的时候都会调用类的构造方法,所以new一次就会调用构造方法一次。
3.如果继承体系中既有构造方法,又有静态代码块,那么首先执行最顶层的类的静态代码块,一直执行到最底层类的静态代码块,然后再去执行最顶层类的构造方法,一直执行到最底层类的构造方法。
注意:静态代码块只会执行一次。
static修饰类: 这个有点特殊,首先,static是可以用来修饰类的,但是static是不允许用来修饰普通类,只能用来修饰内部类,被static所修饰的内部类可以用new关键字来直接创建一个实例,不需要先创建外部类实例。static内部类可以被其他类实例化和引用(即使它是顶级类)。
strictfp 严格,精准
strictfp的意思是FP-strict,也就是说精确浮点的意思。可以将一个类、接口以及方法声明为strictfp,但是不允许对接口中的方法以及构造函数声明strictfp关键字。
在Java虚拟机进行浮点运算时,如果没有指定strictfp关键字时,Java的编译器以及运行环境在对浮点运算的表达式是采取一种近似于我行我素的行为来完成这些操作,以致于得到的结果往往无法令人满意。而一旦使用了strictfp来声明一个类、接口或者方法时,那么所声明的范围内Java的编译器以及运行环境会完全依照浮点规范IEEE-754来执行。因此如果想让浮点运算更加精确,而且不会因为不同的硬件平台所执行的结果不一致的话,那就请用关键字strictfp。
synchronized 线程、同步
synchronized 关键字可以应用于方法或语句块,并为一次只应由一个线程执行的关键代码段提供保护。
synchronized 关键字可防止程序的关键代码段一次被多个线程执行(即指示该段代码一个时刻只能被一个线程访问)。
如果应用于静态方法,那么,当该方法一次由一个线程执行时,整个类将被锁定。
如果应用于实例方法,那么,当该方法一次由一个线程访问时,该实例将被锁定。
如果应用于对象或数组,当关联的代码块一次由一个线程执行时,对象或数组将被锁定。
synchronized 方法控制对类成员变量的访问:
每个类实例对应一把锁,每个synchronized 方法都必须获得调用该方法的类实例的锁方能执行,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法返回时才将锁释放,此后被阻塞的线程方能获得该锁,重新进入可执行状态。这种机制确保了同一时刻对于每一个类实例,其所有声明为 synchronized 的成员函数中至多只有一个处于可执行状态(因为至多只有一个能够获得该类实例对应的锁),从而有效避免了类成员变量的访问冲突(只要所有可能访问类成员变量的方法均被声明为 synchronized)。
在Java中,不光是类实例,每一个类也对应一把锁,这样我们也可将类的静态成员函数声明为 synchronized ,以控制其对类的静态成员变量的访问。
synchronized 方法的缺陷:若将一个大的方法声明为synchronized 将会大大影响效率,典型地,若将线程类的方法 run() 声明为synchronized ,由于在线程的整个生命期内它一直在运行,因此将导致它对本类任何synchronized 方法的调用都永远不会成功。当然我们可以通过将访问类成员变量的代码放到专门的方法中,将其声明为 synchronized ,并在主方法中调用来解决这一问题,但是 Java 为我们提供了更好的解决办法,那就是 synchronized块。
synchronized块:
当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。这里的关键之处在于,这个object的对象锁只有一把,一把锁对应一个线程。
transient 短暂
transient 关键字可以应用于类的成员变量,以便指出该成员变量不应在包含它的类实例已序列化时被序列化(即当对象被序列化时防止transient属性被序列化)。当一个对象被串行化的时候,transient型变量的值不包括在串行化的表示中,然而非transient型的变量是被包括进去的。
Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想用serialization机制来保存它。为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。
transient是Java语言的关键字,用来表示一个域不是该对象串行化的一部分。当一个对象被串行化的时候,transient型变量的值不包括在串行化的表示中,然而非transient型的变量是被包括进去的。
volatile 易失
volatile 关键字用于表示可以被多个线程异步修改的成员变量。
注意: volatile 关键字在许多 Java 虚拟机中都没有实现。 volatile 的目标用途是为了确保所有线程所看到的指定变量的值都是相同的。
Volatile修饰的成员变量在每次被线程访问时,都强迫从主内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比。
这样当多个线程同时与某个对象交互时,就必须要注意到要让线程及时的得到共享成员变量的变化。
而volatile关键字就是提示VM:对于这个成员变量不能保存它的私有拷贝,而应直接与共享成员变量交互。
注意: 由于使用volatile屏蔽掉了VM中必要的代码优化,所以在效率上比较低,因此一定在必要时才使用此关键字。
使用建议:在两个或者更多的线程访问的成员变量上使用volatile。当要访问的变量已在synchronized代码块中,或者为常量时,不必使用。
Java 语言中的 volatile 变量可以被看作是一种 “程度较轻的 synchronized”;与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少,但是它所能实现的功能也仅是 synchronized 的一部分。
native 本地的
native 关键字用于声明方法,以指示该方法是用Java以外的语言实现的,方法对应的实现不是在当前文件,而是在用其他语言(如C和C++)实现的文件中。
Java不是完美的,Java的不足除了体现在运行速度上要比传统的C++慢许多之外,Java无法直接访问到操作系统底层(如系统硬件等),为此Java使用native方法来扩展Java程序的功能。
可以将native方法比作Java程序同C程序的接口,其实现步骤:
1、 在Java中声明native()方法,然后编译。
2、 用javah产生一个.h文件。
3、 写一个.cpp文件实现native导出方法,其中需要包含第二步产生的.h文件(注意其中又包含了JDK带的jni.h文件)。
4、 将第三步的.cpp文件编译成动态链接库文件。
5、 在Java中用System.loadLibrary()方法加载第四步产生的动态链接库文件,这个native()方法就可以在Java中被访问了。
JAVA本地方法适用的情况
1、 为了使用底层的主机平台的某个特性,而这个特性不能通过JAVA API访问
2、 为了访问一个老的系统或者使用一个已有的库,而这个系统或这个库不是用JAVA编写的
3、 为了加快程序的性能,而将一段时间敏感的代码作为本地方法实现。
3.流程控制语句
if-else
if 关键字指示有条件地执行代码块。条件的计算结果必须是布尔值。(即实现二选一的分支语句)
if 语句可以有可选的 else 子句,该子句包含条件为 false 时将执行的代码。条件为包含 boolean 操作数的表达式只能包含 boolean 操作数。
switch-case-default-finally
switch 语句用于基于某个表达式选择执行多个代码块中的某一个。
switch 条件的计算结果必须等于 byte、char、short 或 int。
case 用来标记 switch 语句中的每个分支。
case 块没有隐式结束点。break 语句通常在每个 case 块末尾使用,用于退出 switch 语句。
如果没有 break 语句,执行流将进入所有后面的 case 或 default 块。
default 关键字用来标记 switch 语句中的默认分支。
default 块没有隐式结束点。break 语句通常在每个 case 或 default 块的末尾使用,以便在完成块时退出 switch 语句。
如果没有 default 语句,其参数与任何 case 块都不匹配的 switch 语句将不执行任何操作。
finally关键字用来标记最终的,即无论选择哪个语句,这后面的代码块都是要执行的。
总结: 即实现多选一的分支语句。
for
for 关键字用于指定一个在每次迭代结束前检查其条件的循环。
for 语句的形式为 for(初始条件; 循环继续的条件; 循环每轮要做的动作) {代码块(循环体);}
控件流进入 for 语句时,将执行一次初始条件语句。
每次执行循环体之前将判断一下循环继续的条件是否符合。如果条件为 true,则执行循环体。
每次执行循环体之后,在判断下一个迭代的循环继续的条件之前,将执行一下循环每轮要做的动作。
while
while 关键字用于指定一个只要条件为真就会重复的循环。
while 语句的形式为while(循环条件){代码块(循环体);}
控件流进入 while 语句时,将进行一次条件判断,如果条件为 true,则执行循环体。
do(do-while)
do 关键字用于指定一个在每次迭代结束时检查其条件的循环。do 循环体至少执行一次。 条件表达式后面必须有分号。
do-while 语句的形式为do{代码块(循环体);}while(循环条件);
控件流进入 do-while 语句时,将先执行一下循环体,然后进行条件判断,如果条件为 true,则执行循环体。
循环体至少执行一次。
break
break 关键字用于提前退出本次的 for、while 或 do 循环,或者在 switch 语句中用来结束 case 块(即跳出本次循环执行代码)。
break 总是退出最内层的 while、for、do 或 switch 语句。
continue
continue 关键字用来跳转到 for、while 或 do 循环的下一个迭代(即跳过本次循环,执行下一次的循环)。
continue 总是跳到最内层 while、for 或 do 语句的下一个迭代。
return
return 关键字会导致方法返回到调用它的方法,从而传递与返回方法的返回类型匹配的值。 如果方法具有非 void 的返回类型,return 语句必须具有相同或兼容类型的参数。(即从方法返回到调用它的位置,不会执行余下的代码,若为非void类型,则返回一个与类型相匹配的数)。
4.异常处理
try-catch-finally
try 关键字用于包含可能引发异常的语句块。
catch 关键字用来在 try-catch 或 try-catch-finally 语句中定义异常处理块。
开始和结束标记 ‘{’ ‘}’ 是 catch 子句语法的一部分,即使该子句只包含一个语句,也不能省略这两个标记。
每个 try 块都必须至少有一个 catch 或 finally 子句。
如果某个特定异常类未被任何 catch 子句处理,该异常将沿着调用栈递归地传播到下一个封闭 try 块。如果任何封闭 try 块都未捕获到异常,Java 解释器将退出,并显示错误消息和堆栈跟踪信息。
finally 关键字用来定义始终在 try-catch-finally 语句中执行的块。
在异常处理机制当中,它的作用就像是人吃饭一样,必须得做的,不论有异常还是没有异常都要执行的代码就可以放到finally块当中去。
finally块,必须要配合try块一起使用,不能单独使用,也不能直接和catch块一起使用。
finally 块通常包含清理代码,用在部分执行 try 块后恢复正常运行。
throw
throw 关键字用于抛出异常。
throw 语句将 java.lang.Throwable 作为参数。
Throwable 在调用栈中向上传播,直到被适当的 catch 块捕获。
引发非 RuntimeException 异常的任何方法还必须在方法声明中使用 throws 修饰符来声明它引发的异常。
throws
throws 关键字可以应用于方法,以便声明方法可能抛出引发了的特定类型异常。
throws 关键字将逗号分隔的 java.lang.Throwables 列表作为参数。
引发非 RuntimeException 异常的任何方法还必须在方法声明中使用 throws 修饰符来声明它引发的异常。
要在 try-catch 块中包含带 throws 子句的方法的调用,必须提供该方法的调用者。
5.包控制
import
import 关键字使一个包中的一个或所有类在当前 Java 源文件中可见。可以不使用完全限定的类名来引用导入的类(即“*”操作)。
注意:当多个包包含同名的类时,许多 Java 程序员只使用特定的 import 语句(没有“*”)来避免不确定性。
package
package 关键字指定当前Java源文件中定义的所有类或接口属于哪个包。
package 语句(如果出现)必须是 Java 源文件中的第一个非注释性文本。 例:java.lang.Object。 如果 Java 源文件不包含 package 语句,在该文件中定义的类将位于“默认包”中。
注意:不能从非默认包中的类引用默认包中的类。
6.基本数据类型
byte
byte 是 Java 原始类型,即能表示8位二进制(bits)带符号整数,所以byte 可存储在 [-128, 127] 范围以内的整数值。
Byte 类是 byte 原始类型的包装对象类。
它定义代表此类型的值的范围的 MIN_VALUE 和 MAX_VALUE 常量。
short
short 是 Java 原始类型,即能表示16位二进制(bits)带符号整数。
Short 类是 short 原始类型的包装对象类。
它定义代表此类型的值的范围的 MIN_VALUE 和 MAX_VALUE 常量。
int
int 是 Java 原始类型,即能表示32位二进制(bits)带符号整数。
Integer 类是 int 原始类型的包装对象类。
它定义代表此类型的值的范围的 MIN_VALUE 和 MAX_VALUE 常量。
long
long 是 Java 原始类型。long 变量可以存储 64 位的带符号整数。
Long 类是 long 原始类型的包装对象类。
它定义代表此类型的值的范围的 MIN_VALUE 和 MAX_VALUE 常量。
Java 中的所有整数值都是 32 位的 int 值,除非值后面有 l 或 L(如 235L),这表示该值应解释为 long。
float
float 是 Java 原始类型。float 变量可以存储单精度浮点值。
使用此关键字时应遵循下列规则:
(1) Java 中的浮点文字始终默认为双精度。要指定单精度文字值,应在数值后加上 f 或 F,如 0.01f。
(2) 由于浮点数据类型是实际数值的近似值,因此,一般不要对浮点数值进行是否相等的比较。
(3) Java 浮点数值可代表无穷大和 NaN(非数值)。Float 包装对象类用来定义常量 MIN_VALUE、MAX_VALUE、NEGATIVE_INFINITY、POSITIVE_INFINITY 和 NaN。
double
double 是 Java 原始类型。double 变量可以存储双精度浮点值。
使用此关键字时应遵循下列规则:
(1) 由于浮点数据类型是实际数值的近似值,因此,一般不要对浮点数值进行是否相等的比较。
(2) 浮点数值可代表无穷大和 NaN(非数值)。Double 包装对象类用来定义常量 MIN_VALUE、MAX_VALUE、NEGATIVE_INFINITY、POSITIVE_INFINITY 和 NaN。
char
char 是 Java 原始类型。char 变量可以存储一个 Unicode 字符。
char 常量的转义字符用途:
\b - 空格,
\f - 换页,
\n - 换行
\r - 回车,
\t - 水平制表符
’ - 单引号
" - 双引号
\ - 反斜杠
\xxx - 采用 xxx 编码的 Latin-1 字符
\x 和 \xx 均为合法形式,但可能引起混淆。
\uxxxx - 采用十六进制编码 xxxx 的 Unicode 字符。
Character 类包含一些可用来处理 char 变量的 static 方法,这些方法包括 isDigit()、isLetter()、isWhitespace() 和 toUpperCase()。
char 值没有符号。
boolean
boolean 是 Java 原始类型。boolean 变量的值可以是 true 或 false。
(1) boolean 变量只能以 true 或 false 作为值。boolean 不能与数字类型相互转换。
(2) 包含 boolean 操作数的表达式只能包含 boolean 操作数。
(3) Boolean 类是 boolean 原始类型的包装对象类。
void
void 关键字表示 null 类型。 void 可以用作方法的返回类型,以指示该方法不返回任何数据类型。
7.返回值类型
null
null 是 Java 的保留字,表示无值。
将 null 赋给非原始变量(引用类型变量)相当于释放该变量先前所引用的对象。
注意: 不能将 null 赋给原始类型(byte、short、int、long、char、float、double、boolean)变量。
true
true 关键字表示 boolean 变量中为"真"的值。
false
false 关键字代表 boolean 变量中为"假"的值。
8.引用类型变量
super
super 关键字用于引用使用该关键字的类的超类(即指向当前类的直接父类)。
作为独立语句出现的 super 表示调用超类的构造方法。
super.() 表示调用超类的方法。
注意:只有在如下情况中才需要采用这种用法:
要调用在该类中被重写的方法,以便指定应当调用在超类中的该方法。
this
this 关键字用于引用当前实例(即指向当前类的对象)。 当引用可能不明确时,可以使用 this 关键字来引用当前的实例。
instanceof
instanceof关键字用来判断一个对象是否为一个类或接口的对象,在类型上溯造型或下溯造型情况下经常使用。
9.保留字
goto
goto 保留关键字,但无任何作用。
结构化程序设计完全不需要 goto 语句即可完成各种流程,而 goto 语句的使用往往会使程序的可读性降低,所以 Java 不允许 goto 跳转。
const
const 保留字,是一个类型修饰符,使用const声明的对象不能更新。与final某些类似。
三、分隔符( 要求必须用英文半角字符)
空格(space)
主要用于关键字、标识符之间。
跳格(tab)
常用于代码缩进,一般设置为四个空格。
小数点(Decimal Point)
用于包路径的分隔符也用于调属性的功能(用在包和包、包和类、类和方法、对象和方法、类和属性、对象和属性等成分之间)。
分号(Semicolon)
每一条Java语句必须以";"结束。 Java允许将一个长语句写道多行中,但前提是不能断开关键字和String常量。
{ }
用于定义类体、方法体、语句块、数组静态初始化等成分。
[ ]
用于数组的定义和使用中。
( )
用于方法的定义和方法的调用。
双引号(" ")
用于字符串String常量中。
单引号(’ ')
用于字符串常量中。
四、运算符,表达式与语句
运算符(Operator)
计算机的最基本用途之一就是执行数学运算,作为一门计算机语言,Java也提供了一套丰富的运算符来操纵变量。
Java中我们可以把运算符分为以下几类:
(1)算术运算符
(2)关系运算符
(3)位运算符
(4)逻辑运算符
(5)赋值运算符
(6)其他运算符
(1)算术运算符
常见算数运算符表
操作符 | 描述 | 例子 |
---|---|---|
+ | 加法 - 相加运算符两侧的值 | A + B 等于 30 |
- | 减法 - 左操作数减去右操作数 | A – B 等于 -10 |
* | 乘法 - 相乘操作符两侧的值 | A * B等于200 |
/ | 除法 - 左操作数除以右操作数 | B / A等于2 |
% | 取余 - 左操作数除以右操作数的余数 | B%A等于0 |
++ | 自增: 操作数的值增加1 | B++ 或 ++B 等于 21(区别详见下文) |
– | 自减: 操作数的值减少1 | B-- 或 --B 等于 19(区别详见下文) |
实例
public class Test {
public static void main(String[] args) {
int a = 10;
int b = 20;
int c = 25;
int d = 25;
System.out.println("a + b = " + (a + b) );
System.out.println("a - b = " + (a - b) );
System.out.println("a * b = " + (a * b) );
System.out.println("b / a = " + (b / a) );
System.out.println("b % a = " + (b % a) );
System.out.println("c % a = " + (c % a) );
System.out.println("a++ = " + (a++) );
System.out.println("a-- = " + (a--) );
// 查看 d++ 与 ++d 的不同
System.out.println("d++ = " + (d++) );
System.out.println("++d = " + (++d) );
}
}
以上代码编译执行后的结果:
a + b = 30
a - b = -10
a * b = 200
b / a = 2
b % a = 0
c % a = 5
a++ = 10
a-- = 11
d++ = 25
++d = 27
自增自减运算符解析
1、自增(++)自减(–)运算符是一种特殊的算术运算符,在算术运算符中需要两个操作数来进行运算,而自增自减运算符是一个操作数。
实例
public class selfAddMinus{
public static void main(String[] args){
int a = 3;//定义一个变量;
int b = ++a;//自增运算
int c = 3;
int d = --c;//自减运算
System.out.println("进行自增运算后的值等于"+b);
System.out.println("进行自减运算后的值等于"+d);
}
}
以上代码编译执行后的结果:
进行自增运算后的值等于4
进行自减运算后的值等于2
解析:
int b = ++a; 拆分运算过程为: a=a+1=4; b=a=4, 最后结果为b=4,a=4。
int d = --c; 拆分运算过程为: c=c-1=2; d=c=2, 最后结果为d=2,c=2。
2、前缀自增自减法(++a,–a): 先进行自增或者自减运算,再进行表达式运算。
3、后缀自增自减法(a++,a–): 先进行表达式运算,再进行自增或者自减运算 。
实例
public class selfAddMinus{
public static void main(String[] args){
int a = 5;//定义一个变量;
int b = 5;
int x = 2*++a;
int y = 2*b++;
System.out.println("自增运算符前缀运算后a="+a+",x="+x);
System.out.println("自增运算符后缀运算后b="+b+",y="+y);
}
}
以上代码编译执行后的结果:
自增运算符前缀运算后a=6,x=12
自增运算符后缀运算后b=6,y=10
(2)关系运算符
常见关系运算符表
运算符 | 描述 | 例子 |
---|---|---|
== | 检查如果两个操作数的值是否相等,如果相等则条件为真。 | (A == B)为假。 |
!= | 检查如果两个操作数的值是否相等,如果值不相等则条件为真。 | (A != B) 为真。 |
> | 检查左操作数的值是否大于右操作数的值,如果是那么条件为真。 | (A> B)为假。 |
< | 检查左操作数的值是否小于右操作数的值,如果是那么条件为真。 | (A <B)为真。 |
>= | 检查左操作数的值是否大于或等于右操作数的值,如果是那么条件为真。 | (A> = B)为假。 |
<= | 检查左操作数的值是否小于或等于右操作数的值,如果是那么条件为真。 | (A <= B)为真。 |
实例
public class Test {
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println("a == b = " + (a == b) );
System.out.println("a != b = " + (a != b) );
System.out.println("a > b = " + (a > b) );
System.out.println("a < b = " + (a < b) );
System.out.println("b >= a = " + (b >= a) );
System.out.println("b <= a = " + (b <= a) );
}
}
以上代码编译执行后的结果:
a == b = false
a != b = true
a > b = false
a < b = true
b >= a = true
b <= a = false
(3)位运算符
Java定义了位运算符,应用于整数类型(int),长整型(long),短整型(short),字符型(char),和字节型(byte)等类型。
位运算符作用在所有的位上,并且按位运算。假设a = 60,b = 13;它们的二进制格式表示将如下:
A = 0011 1100
B = 0000 1101
操作完二进制结果如下:
A&B = 0000 1100
A|B = 0011 1101
A^B = 0011 0001
~A = 1100 0011
下表列出了位运算符的基本运算
假设整数变量 A 的值为 60 和变量 B 的值为 13:
操作符 | 描述 | 例子 |
---|---|---|
& | 如果相对应位都是1,则结果为1,否则为0 | (A&B),得到12,即0000 1100 |
或,英文状态下竖线 | 如果相对应位都是 0,则结果为 0,否则为 1 | (A 或 B)得到61,即 0011 1101 |
^ | 如果相对应位值相同,则结果为0,否则为1 | (A ^ B)得到49,即 0011 0001 |
〜 | 按位取反运算符翻转操作数的每一位,即0变成1,1变成0。 | (〜A)得到-61,即1100 0011 |
<< | 按位左移运算符。左操作数按位左移右操作数指定的位数。 | A << 2得到240,即 1111 0000 |
>> | 按位右移运算符。左操作数按位右移右操作数指定的位数。 | A >> 2得到15即 1111 |
>>> | 按位右移补零操作符。左操作数的值按右操作数指定的位数右移,移动得到的空位以零填充。 | A>>>2得到15即0000 1111 |
实例
public class Test {
public static void main(String[] args) {
int a = 60; /* 60 = 0011 1100 */
int b = 13; /* 13 = 0000 1101 */
int c = 0;
c = a & b; /* 12 = 0000 1100 */
System.out.println("a & b = " + c );
c = a | b; /* 61 = 0011 1101 */
System.out.println("a | b = " + c );
c = a ^ b; /* 49 = 0011 0001 */
System.out.println("a ^ b = " + c );
c = ~a; /*-61 = 1100 0011 */
System.out.println("~a = " + c );
c = a << 2; /* 240 = 1111 0000 */
System.out.println("a << 2 = " + c );
c = a >> 2; /* 15 = 1111 */
System.out.println("a >> 2 = " + c );
c = a >>> 2; /* 15 = 0000 1111 */
System.out.println("a >>> 2 = " + c );
}
}
以上代码编译执行后的结果:
a & b = 12
a | b = 61
a ^ b = 49
~a = -61
a << 2 = 240
a >> 2 = 15
a >>> 2 = 15
(4)逻辑运算符
下表列出了逻辑运算符的基本运算
假设布尔变量A为真,变量B为假
操作符 | 描述 | 例子 |
---|---|---|
&& | 称为逻辑与运算符。当且仅当两个操作数都为真,条件才为真。 | (A && B)为假。 |
短路或,英文状态下两个竖线 | 称为逻辑或操作符。如果任何两个操作数任何一个为真,条件为真。 | (A 短路或 B)为真。 |
! | 称为逻辑非运算符。用来反转操作数的逻辑状态。如果条件为true,则逻辑非运算符将得到false。 | !(A && B)为真。 |
实例
public class Test {
public static void main(String[] args) {
boolean a = true;
boolean b = false;
System.out.println("a && b = " + (a&&b));
System.out.println("a || b = " + (a||b) );
System.out.println("!(a && b) = " + !(a && b));
}
}
以上代码编译执行后的结果:
a && b = false
a || b = true
!(a && b) = true
注意:短路逻辑运算符
当使用与逻辑运算符时,在两个操作数都为true时,结果才为true,但是当得到第一个操作为false时,其结果就必定是false,这时候就不会再判断第二个操作了。
实例
public class LuoJi{
public static void main(String[] args){
int a = 5;//定义一个变量;
boolean b = (a<4)&&(a++<10);
System.out.println("使用短路逻辑运算符的结果为"+b);
System.out.println("a的结果为"+a);
}
}
以上代码编译执行后的结果:
使用短路逻辑运算符的结果为false
a的结果为5
解析:
该程序使用到了短路逻辑运算符(&&),首先判断 a<4 的结果为 false,则 b 的结果必定是 false,所以不再执行第二个操作 a++<10 的判断,所以 a 的值为 5。
(5)赋值运算符
常见赋值运算符表
操作符 | 描述 | 例子 |
---|---|---|
= | 简单的赋值运算符,将右操作数的值赋给左侧操作数 | C = A + B将把A + B得到的值赋给C |
+ = | 加和赋值操作符,它把左操作数和右操作数相加赋值给左操作数 | C + = A等价于C = C + A |
- = | 减和赋值操作符,它把左操作数和右操作数相减赋值给左操作数 | C - = A等价于C = C - A |
* = | 乘和赋值操作符,它把左操作数和右操作数相乘赋值给左操作数 | C * = A等价于C = C * A |
/ = | 除和赋值操作符,它把左操作数和右操作数相除赋值给左操作数 | C / = A,C 与 A 同类型时等价于 C = C / A |
(%)= | 取模和赋值操作符,它把左操作数和右操作数取模后赋值给左操作数 | C%= A等价于C = C%A |
<< = | 左移位赋值运算符 | C << = 2等价于C = C << 2 |
>> = | 右移位赋值运算符 | C >> = 2等价于C = C >> 2 |
&= | 按位与赋值运算符 | C&= 2等价于C = C&2 |
^ = | 按位异或赋值操作符 | C ^ = 2等价于C = C ^ 2 |
或= | 按位或赋值操作符 | C 或 = 2等价于C = C 或 2 |
实例
public class Test {
public static void main(String[] args) {
int a = 10;
int b = 20;
int c = 0;
c = a + b;
System.out.println("c = a + b = " + c );
c += a ;
System.out.println("c += a = " + c );
c -= a ;
System.out.println("c -= a = " + c );
c *= a ;
System.out.println("c *= a = " + c );
a = 10;
c = 15;
c /= a ;
System.out.println("c /= a = " + c );
a = 10;
c = 15;
c %= a ;
System.out.println("c %= a = " + c );
c <<= 2 ;
System.out.println("c <<= 2 = " + c );
c >>= 2 ;
System.out.println("c >>= 2 = " + c );
c >>= 2 ;
System.out.println("c >>= 2 = " + c );
c &= a ;
System.out.println("c &= a = " + c );
c ^= a ;
System.out.println("c ^= a = " + c );
c |= a ;
System.out.println("c |= a = " + c );
}
}
以上代码编译执行后的结果:
c = a + b = 30
c += a = 40
c -= a = 30
c *= a = 300
c /= a = 1
c %= a = 5
c <<= 2 = 20
c >>= 2 = 5
c >>= 2 = 1
c &= a = 0
c ^= a = 10
c |= a = 10
(6)其他运算符
条件运算符(?:)
条件运算符也被称为三元运算符。该运算符有3个操作数,并且需要判断布尔表达式的值。该运算符的主要是决定哪个值应该赋值给变量。
三元运算符使用格式如下:
variable x = (expression) ? value if true : value if false
实例
public class Test {
public static void main(String[] args){
int a , b;
a = 10;
// 如果 a 等于 1 成立,则设置 b 为 20,否则为 30
b = (a == 1) ? 20 : 30;
System.out.println( "Value of b is : " + b );
// 如果 a 等于 10 成立,则设置 b 为 20,否则为 30
b = (a == 10) ? 20 : 30;
System.out.println( "Value of b is : " + b );
}
}
以上代码编译执行后的结果:
Value of b is : 30
Value of b is : 20
instanceof 运算符
该运算符用于操作对象实例,检查该对象是否是一个特定类型(类类型或接口类型)。
instanceof运算符使用格式如下:
( Object reference variable ) instanceof (class/interface type)
如果运算符左侧变量所指的对象,是操作符右侧类或接口(class/interface)的一个对象,那么结果为真。
例:
String name = “James”;
boolean result = name instanceof String; // 由于 name 是 String 类型,所以返回真
如果被比较的对象兼容于右侧类型,该运算符仍然返回true。
实例
class Vehicle {}
public class Car extends Vehicle {
public static void main(String[] args){
Vehicle a = new Car();
boolean result = a instanceof Car;
System.out.println( result);
}
}
以上代码编译执行后的结果:
true
表达式(Expression)
由常量、变量、方法、运算符、括号等成分组成的合法的有意义的式子(即有运算符的式子)就叫表达式。
语句(Statement)
是构成程序的基本单位,可以对计算机发出操作指令。
每个Java语句必须以";"结束。
Java的主要语句:
(1)方法调用语句
(2)赋值语句
(3)复合语句或语句块
(4)流程控制语句
(5)package、import语句
(6)注释(Comment)语句 :单行注释//…;多行注释/…/;文档注释/* …/。
Java注释
注释(Comment):程序中的说明性文字(程序的功能、结构、版权等信息),可增强程序的可读性和易维护性,有三种形式。
单行注释
注解的内容只能在一行上面,不能换行。
格式为:
//…
多行注释
注解的内容可以换行,可以嵌套多行注释,但多行注释不能相互嵌套。
格式为:
/ *…* /
文档注释
会被Javadoc.exe文档工具读取,生成标准的HTML帮助文档。
格式为:
/ **…*/