第二章 JAVA 基本语法
method修饰符
final
final method 不可以被子类覆盖或隐藏,它可以达成对正常method来说不可ide编译器最佳化。所有的private method其实都是final,就如同同类中所有的method都会被声明为final一样。
声明已查核异常
Error 未查核异常
Exeption 已查核异常(除了java.lang.RuntimeException)
不定长度的自变量列表
在Java 5.0或以上的版本中,method可被声明为可接受补丁数量的自变量,而且也可以被不定数量的自变量所调用。这种method就是我们所说的varargs method。新的System.out.printf() method及与其相关的String的format() method和 java.util.Formatter都是用了varargs.相似但不相关的java.text.MessageFormate的format() method已经被转换为使用varargs,就像java.lang.refect的reflelctionAPI的一样重要method一样
一个不定长度的自变量列表的声明是在method里使用省略号(...)来表示该method可以接受不定长度的自变量,并指出其自变量可以被重复零次或多次。例如:
public class MaxTest { public static int max(int first, int... rest){ int max = first; for(int i:rest){ if(i>max)max=i; } return max; } public static void main(String[] args) { System.out.println(max(0)); System.out.println(max(1,2)); System.out.println(max(16,8,4,2,1)); } }
上述的max() method声明了两个变量,第一个是正常的int值,第二个则可以被重复零次或更多次。以下使用max()的方式都是合法的:
max(0) max(1,2) max(16,8,4,2,1)
就如你从max()主体中的for/in语句所看到的,第二个自变量可被视为由int值组成的数组。varargs method完全都是由编译器处理。对Java解释器来说,max() method和以下的程序没有两样:
public static int max(int first, int[] rest)
char
char是一个数据类型,它表示一个Unicode字符,但一个char值所代表的则是某个特定字符
for/in 语句
for/in语句是Java5.0中新加入的具有强大的循环功能的语句。它通过数组的元素、集合、可以实现java.lang.Iterable的对象来不断地重复执行。每一个iteration会赋予一个数组元素或Iterable对象给你所声明的循环变量,然后执行该循环主体,该循环主题一般都是使用循环变量来操作里面的元素。for/in语句中不需要使用到任何的循环计数器或Iterable对象,它会自动地重复执行,并且你不需要为初始值正确与否或循环结束而担心。
for/in循环后面紧接着的是一个左小括号、变量的声明(不需做初始化)、冒号、表达式、一个右小括号,最后一个就是它的语句(或代码块)。这就是此循环主体的格式。
for( declaration : expression) statement
for/in循环并没有使用关键字in,且一般都会将该循环的冒号读成"in".因为这个语句没有属于自己的关键字,因此就不会和另一个for循环造成混淆。或许你也会看到有人称它“enhanced for” 或 “foreach”.
我们已经使用了while、do与for循环来编写可以显示出10个数字的范例,同样的,for/in循环也可以做到,但不能仅靠该循环本身。for/in是不同于其他一般用途的一个很特殊的循环,它会对每一个数组或集合内的元素执行一次该循环主体,所以如果要执行循环10次(显示10个数字),我们就需要拥有10个元素的数组或集合。
比如
//这些是我们想要显示出来的数字 int[] primes = new int[] {2,3,5,7,11,13,17,19,23,29}; //这个可以将他们显示出来的循环 for(int n : primes) Sysout.out.println(n);
以下是关于for/in循环,你所必需知道的语法:
内存分配与内存回收
我们先前提到过,对象是符合数据类型,它们可以拥有任意数量的值且需要相当的内存空间。当你使用new关键字创建一个新的对象或是在程序中使用一个对象或直接量时,Java会自动地为你创建该对象,同时分配它所需的内存空间。你不需要亲自去做这些事。
此外,Java也会自动地回收已经不再使用的内存空间,它会通过内存回收(garbage collection)机制来做这件事。当一个对象已经没有任何存储与变量、对象的字段、数组元素的引用指向它时,它会被认为是没有用的。例如:
Poing p = new Poing(1,2); //创建一个对象 double d = p .distanceFromOrigin(); //使用它来做某些事 p = new Point(2,3); //创建一个新的对象
在Java解释器执行过第三行代码之后,该引用会指向一个新的Point对象,而不再指向旧的Point对象。现在已经没有任何的引用指向该旧的对,因此它变成了一个无用的对象。内存回收程序(garbage collector)将会发现这一点,并将该对象所使用的内存给释放出来。
C程序员习惯使用malloc()与free()来管理内存,而C++程序员则习惯使用delete来删除对象,似乎认为将这些事情都由内存回收程序来处理是一件不太令人放心的事情。虽然它看起来有点不可思议,但真的就是能百分之百达到这样的功能。当使用内存挥手程序时,性能会有些微下降,而JAVA程序在运行中速度有时候也会突然地变慢,这是因为内存回收程序正在回收内存关系。然后,将内存回收功能内置于语言中会降低内存泄漏(memeory leak)的发生几率,程序错误数也会相对减少,并改善程序员的生产效率。
引用类型的转换
Object o ="string"; //从String 到 Object 的放大转换 String s = (String) o; // 从Object 到 String 的缩小转换
Java 与 C 的不同点
没有预处理器
java没有与处理器(preprocessor),因此并未定义类似#define、#include与#ifdef的指令.Java中的常量定义也被static final字段所取代(例如 java.lang.Math.PI字段)。在JAVA里也可以定义宏,但高级的编译技术和内联(inlining)已经让宏觉无用处。JAVA并不需要#include指令,这是因为JAVA并没有头文件(header file).Java类文件同时含有类API与该类的实现,而编译器会在需要时从类文件中读取API信息。JAVA也没有任何形式的条件编译模式,但因为它有跨平台的可移植性,所以代表此特性并不十分需要。
没有全局变量
java定义了一个非常整洁的命名空间。包包含了类,类包含了类,类包含了字段与方法,而方法包含了局部变量。但JAVA中并没有全局变量,所以在变量中不可能发生名称冲突的状况。
明确定义的基本数据类型大小
java中的所有基本数据类型都具有定义明确的大小,但在C中,short、int与long类型的大小则会依据平台而不同,这使得C的可移植性受到了阻碍。
没有指针
Java类与数组都是引用类型,对对象与数组的引用和C中的指针相当类似。然而与C指针不同的是,Java中的引用相当复杂,你没有办法将一个引用类型转换为基本数据类型,而且引用类型也无法递加或递减。没有像&的地址运算符,也米有像*或
->的解引用运算符,也没有sizeof运算符。许多程序错误的产生原因是因为指针。将它们消除可简化语言,并且让Java程序更强壮、更安全。
内存回收
JVM会执行内存回收的操作,因此,Java程序员不需为内存管理方面的问题而烦恼。这个特点也大大地减少了程序错误的发生机会,同时也降低了JAVA程序发生内存泄漏的几率。
没有goto语句
Java并不支持goto语句,除了一些特定情况之外,在程序中使用goto语句通常被认为是相当糟糕的实践方法。JAVA除了拥有C所提供的流程控制语句之外,还加入了异常处理以及break和continue语句,它们都是goto的极佳替代品。
可在任何地方声明变量
向前引用
方法重载
没有struct与union类型
没有位域(bitfield)
没有typedef
没有方法指针