阶段0:拟出一个计划
阶段1:要制作什么?
阶段2:如何构建?
阶段3:开始创建
阶段4:校订
阶段5:计划的回报
一、程序运行时,数据保存位置
1、寄存器。这是最快的保存区域,因为它位于和其他所有保存方式不同的地方:处理器内部。然而,寄存器的数量十分有限,所以寄存器是根据需要编译器分配。我们对此没有直接的控制权,也不可能在自己的程序里找到寄存器存在的踪迹。
2、堆栈。驻留于常规RAM(随机访问存储器)区域,但可通过他的“堆栈指针”获得处理的直接支持。堆栈指针若向下移,会创建新的内存;若向上移,则会释放那些内存。这是一种特别快、特别有效的数据保存方式,仅次于寄存器。创建程序时,Java编译器必须准确地知道堆栈内保存的所有数据的“长度”以及“存在时间”。这是由于它必须生成相应的代码,以便向上和向下移动指针。这一限制无疑影响了程序的灵活性,所以尽管有些Java数据要保存在堆栈里——特别是对象句柄,但Java对象并不放到其中。
3、堆。一种常规用途的内存池(也在RAM区域),其中保存了Java对象。和堆栈不同,“内存堆”或“堆”(heap)最吸引人的地方在于编译器不必知道要从堆里分配多少存储空间,也不必知道存储的数据要在堆里停留多长时间。因此,用堆保存数据时会得到更大的灵活性。要求创建一个对象时,只需用new命令编制相关的代码即可。执行这些代码时,会在堆里自动进行数据的保存。当然,为达到这种灵活性,必然会付出一定的代价:在堆里分配存储空间时会花掉更长的时间!
4、静态存储。这儿的“静态”(static)是指“位于固定位置”(尽管也在RAM里)。程序运行期间,静态存储的数据将随时等候调用。可用static关键字指出一个对象的特定元素是静态的。但Java对象本身永远都不会置入静态存储空间。
5、常数存储。常数值通常直接置于程序代码内部。这样做的安全的,因为他们永远都不会改变。有的常数需要严格的保护,所以可考虑将他们置入只读存储器(ROM)。
6、非RAM存储。若数据完全独立于一个程序之外,则程序不运行时仍可存在,并在程序的控制范围之外。其中两个最主要的例子便是”流式对象“和”固定对象“。对于流式对象,对象会变成字节流,通常会发给另一台机器。而对于固定对象,对象保存在磁盘中。即使程序中止运行,它们仍然可保存自己的状态不变。对于这些类型的数据存储,一个特别有用的技巧就是它们能存在于其他媒体中。一旦需要,甚至能够将它们恢复成普通的、基于RAM的对象。
二、主要数据类型
主类型 大小 封装器
1、boolean 1位 Boolean
2、char 16位 Character
3、byte 8位 Byte
4、short 16位 Short
5、int 32位 Integer
6、long 64位 Long
7、float 32位 Float
8、double 64位 Double
假如想让堆内一个非主要对象表示那个朱类型,就要使用对应的封装器,例如:
char c = 'x';
Character C = new Character('c');
也可以直接使用:Character C = new Character('x');
高精度数字:BigInteger和BigDecimal
能对int和float做的事情,对BigInteger和BigDecimal一样可以做。只是必须使用方法调用,不能使用运算符。由于牵涉更多,所以运算速度会慢一些。我们牺牲了速度,但换来了精度。
BigInteger支持任意精度的整数。也就是说,可精确表示任意大小的整数值,同时在运算过程中不会丢失任何信息。
BigDecimal支持任意精度的定点数字。例如,可用它进行精确的币值计算。
三、使用其他组件
import关键字准确告诉Java编译器我们希望的类是什么。import的作用是指示编译器导入一个“包”——或者说一个“类库”。
import java.util.Vector;
它的作用是告诉编译器我们想使用Java的Vector类。当util包含了数量众多的类时,我们想使用其中几个,同时不想全部明确地声明他们,可使用“*”通配符
import java.util.*;
四、static关键字
一旦将什么东西设为static方法,数据或方法就不会同那个类的任何对象实例联系到一起。所以尽管从未创建那个类的一个对象,仍然能调用一个static方法,或访问一些static数据。
对于非static数据和方法,我们必须创建一个对象,并用那个对象访问数据或方法。这是由于非static数据和方法必须知道它们操作的具体对象。
为了将数据成员或方法设为static,只需在定义前置和这个关键字即可。例如下面代码能生成一个static数据成员,并对其初始化:
class StaticTest{
Static int i = 47;
}
除了使用创建StaticTest对象来引用一个static变量,在这里还可以直接用它的类名引用。如StaticTest.i++;
类似的逻辑也适用于静态方法,既可像对其他任何方法那样通过一个对象引用静态方法,也可以用特殊的语法格式“类名.方法()”加以引用。例如:
class StaticFun{
static void incr() {StaticTest.i++; }
}
方法一:典型的方法调用incr();
StaticFun sf = new StaticFun();
sf.incr();
方法二:
StaticFun.incr();
对方法来说,static一项重要的用途就是帮助我们在不必创建对象的前提下调用那个方法。
五、暂停输出
在某些编程环境里,程序会在屏幕上一切而过,甚至没机会看到结果,可将下面这段代码置于main()的末尾,用它暂停输出:
try{
thread.currentThead().sleep(5*1000);
} catch(InterruptException e) {};
}
它的作用是暂停输出5秒钟。
六、第一个Java程序
//Property.java
import java.util.*;
public class Property{
public static void main(String[] args) {
System.out.println(new Data());
Properties p = System.getProperties();
p.list(System.out);
System.out.println("---Memory Usage:");
Runtime rt = Runtime.getRuntime();
System.out.println("Total Memory = "
+rt.totalMemory()
+"Free Memory = "
+rt.freeMemory());
}
}
在每个程序文件的开头。都必须放置一个import语句,导入那个文件的代码里要用到的所有额外的类。注意我们说她们是“额外”的,因为一个特殊的类库会自动导入每个java文件:java.lang。启动您的Web浏览器,查看由Sun提供的用户文档。在packages.html文件里,可找到Java配套提供的所有类库名称。请选择其中的java.lang。在“Class Index”下面,可找到属于那个库的全部类的列表。由于java.lang默认进入每个Java代码文件,所以这些类在任何时候都可直接使用。在这个列表里,可发现System和Runtime,我们在Property.java里用到了它们。java.lang里没有列出Data类,所以必须导入另一个类库才能使用它。如果不清楚一个特定的类在哪个类库里,或者想检视所有的类,可在Java用户文档里选择“Class Hierarchy”(类分级结构)。在Web浏览器中,虽然要花不短的时间来建立这个结构,但可清楚找到与Java配套提供的每一个类。随后,可用浏览器的“查找”(Find)功能搜索关键字“Data”。经这样处理后,可发现我们的搜索目标以java.util.Data的形式列出。我们终于知道它位于util库里,所以必须导入java.util.*;否则便不能使用Data
观察packages.html文档最开头的部分,请选择java.lang,再选System。这时可看到System类有几个字段。若选择out,就可知道它是一个static PrintStream对象。由于它是“静态”的,所以不需要我们创建任何东西。out对象肯定是3,所以只需直接用它即可。我们能对这个out对象做的事情由它的类型决定:PrintStream。PrintStream在说明文字中以一个超链接的形式列出,这一点做的非常方便。所以假若单击那个链接,就可看到能够为PrintStream调用的所有方法。就目前来说,我们感兴趣的*println()。它的意思是“把我给你的东西打印到控制台,并用一个新行结束”。所以在任何Java程序中,一旦要把某些内容打印到控制台,就可条件反射的写上System.out.println("内容");
类名和文件是一样的。若象现在这样创建一个独立的程序,文件中的一个类必须与文件同名(如果没有这样做,编译器会及时作出反应)。类里必须包含一个名为main()的方法,形式如下:
public static void main(String[] args){}
其中,关键字“public”意味着方法可由外部世界调用。main()自变量是包含了String对象的一个数组。args不会在本程序中用到,但需要在这个地方列出,因为它们保存了在命令行调用的自变量。
程序第一行非常有趣:
System.out.println(new Data());
创建Data对象唯一的目的就是将他的值发送给println()。一旦这个语句执行完毕,Data就不再需要。随之而来的“垃圾收集器”会发现这一情况,并在任何可能的时候将其回收。
第二行调用了System.getProperties()。若用Web浏览器查看联机用户文档,就可知道getProperties()是System类的一个static方法。由于它是“静态”的,所以不必创建任何对象便可调用该方法。无论是否存在该类的一个对象,static方法随时都可使用。调用getProperties()时,它会将系统属性作为Properties类的一个对象生成(注意Properties是“属性”的意思)。随后的句柄保存在一个名为p的Properties句柄里。
在第三行,大家可看到Properties对象有一个名为list()的方法,它将自己的全部内容都发给一个我们作为自变量传递的PrintStream对象。
注意为了打印出多个String值,用加号(+)分隔它们即可。在String对象中使用时,加号并不代表真正的“相加”。处理字符串时,我们通常不必考虑“+”的任何特殊含义。但是,Java的String类要受一种名为“运算符过载”的机制的制约。也就是说,只有在随同String对象使用时,加号才会产生于其他任何地方不同的表现。对于字串,它的意思就是“连接这两个字串”。
其中,totalMemory()和freeMemory()返回的是数值,并非String对象。如果将一个数字”加“到一个字串身上,编译器会自动将那个数值(int,float等)转换成字串。经这样处理后,它们当然能利用加号”加“到一起。