日积跬步02
重要思想继续:
1.对象的创建和存在时间:对象需要的数据位于哪儿?如何控制对象的“存在时间”呢?
方法一,C++认为程序的执行效率是最重要的,所以允许程序员为获得最快的运行速度,自行决定存储以及存在时间——只需将对象放置在堆栈或者静态存储区域,同时牺牲灵活性,因为在编写程序时必须准确知道对象数量、存在时间以及类型。
方法二,在内存池中动态创建对象,给内存池叫“堆”或“内存堆”。采用这种方式,除非进入运行期,否则根本不知道实际需要多少个对象,也不知道存在时间以及准确类型。由于动态创建方法使对象本来就倾向于复杂,所以查找存储空间以及释放它所需的额外开销不会为对象的创建造成明显的影响。
如果在堆栈或者静态存储空间里创建一个对象,编译器会判断对象的持续时间有多长,到时会自动“破坏”或者“清除”它。程序员用两种方法破坏对象:一是用程序化的方式消除对象,二是利用运行环境提供的“垃圾收集器”特性,垃圾收集器会自动寻找不再使用的对象并消除,但会额外带来开销。这并不符合C++的语言宗旨,C++严格要求使用完对象必须及时释放。而Java提供了垃圾收集器设计。
2.违例控制:这里的“违例”(Exception)属于一个特殊对象,它会从产生错误的地方“扔”出来 ,随后这个违例会被“违例控制器”捕获,甚至会有多个违例控制器并行捕获对应违例对象。这种设计理念是在不干扰常规代码执行的情况下,独立处置违例错误,最后利用违例从糟糕的环境中恢复,程序不用退出就能恢复执行。
3.多线程:Java的多线程机制已经内建到语言中,简化了复杂的多线程。Java对多线程处理的支持是在对象一级的,所以一个执行线程可表达为一个对象,Java也提供有限的资源锁定方案,它能锁定任何对象占用的内存,即同一时间只能有一个线程使用特定的内存空间。关键字synchronized。
4. java客户端程序、java服务器端程序。。。。
==============================================================================================
“磨刀不误砍柴工”,学习java基本组件:
Chapter2 一切都是对象
1. 一切都是对象,然而操纵标识符实际是指向一个对象的“句柄”,(有参考书的说法是“引用”,甚至“指针”等)。String s; 这里创建的是句柄,而不是对象;始终坚持一个原则:创建句柄时,无论如何必须初始化。
String s = "asdf"; 可以解释为String是一种特殊类型——字串可用加引号的文字初始化。更通用的初始化方法:
String s = new String("asdf");
2.程序运行时,数据保存在什么地方?(非常喜欢作者能一直关注到代码运行内存保存情况,这是一程序员应该考虑的事情,而不是一个拼凑代码的码农care的)
一般来说,有6个地方可以保存数据:
(1)寄存器:速度最快的保存区域,然而寄存器数量有限,由编译器根据需要分配,对程序员来所透明;
(2)堆栈:常规RAM(随机访存)区域,特点是特别快速、特别有效,指针上下移动即可完成内存创建、删除;Java编译器必须明确所保存数据的长度、以及存在时间,这会限制程序的灵活性。一般对象句柄保存在堆栈,而java对象不保存在堆栈;
(3)堆:一种常规用途的内存池(RAM区域),其中保存Java对象。“内存堆”(Heap)最大亮点是编译器不必知道需要从堆里分配多少空间,也不必知道存储的数据在堆停留多长时间;灵活性的代价是堆里分配空间会花掉较长时间;
(4)静态存储:“静态”static是指“位于固定位置”,静态存储的数据随时等候调用,关键字static指定。可以理解保存在RAM的中的静态区域;
(5)常数存储:可直接置于程序代码内部,也可保存在ROM;
(6)非RAM存储:数据完全独立一个程序之外,程序运行时仍可存在。“流式对象”和“固定对象”。
3. Primitive 类型:一些频繁使用、需要特别对待的类型,也叫基本类型。这些简单的、小的变量没必要保存在内存堆。Java采用C/C++方法,不用new创建变量,二是创建一个非句柄的“自动”变量。这些变量容纳具体值,并保存在堆栈中,存取高效;
常用的主类型:boolean char byte short int long float double Void
需要注意的是:数值类型全部都是有符号的;主数据类型拥有自己的“封装器”(wrapper)类。高精度计算:BigInteger和BigDecimal,两者都没有对应“主类型”,需要通过方法调用。
单独说一下数组,C和C++中数组就是实际的内存块,如果越界访问或未初始化,会产生不可预测后果(C++优先使用标准模板库的容器)。Java推崇安全性的设计目标——系统自动进行范围检查,缺点是会造成少量内存开销。创建对象数组,实际创建的是一个句柄数组,每个句柄初始化成特殊值null,Java强制要求在使用前句柄指向一个对象。
4.作用域和存在时间
例子:
{
int x = 12;
/* only x available */
{
int q = 96;
/* both x & q available */
}
/* only x available */
/* q “out of scope” */
}
作为在作用域里定义的变量,只有在作用域结束之前才能使用。
Java对象的存活时间不同于主类型。new创建的Java对象,存活周期会超过作用域的范围。
{
String s = new String("a string")
}/*作用域的终点*/
句柄s会在作用域终点处消失,而s指向的对象依然占据内存,只要你愿意,甚至可以一直保留下去。好任性的说,因为Java的内存垃圾收集器特性,避免了C++程序员忘记释放内存导致的“溢出问题”。
5.类、成员和方法
关键字class定义一个类,类的基本元素:类成员和类方法。
类成员是一种对象(通过句柄与其通信),类成员可以是任何类型,或者是主类型,或者是指向对象的句柄。如果是对象句柄,必须使用“构建器”初始化;而如果是主类型,可直接在定义位置初始化;
类方法的基本形式:
返回类型 方法名(/* 自变量列表 */) {/* 方法主体 */}
自变量列表规定了传送给类方法的信息,这些信息采用对象的形式,实际传递的是对象“句柄”。主数据类型是例外。
若返回类型是void,则关键字return的唯一作用是退出方法。所以一旦到达方法末尾,该关键字可不需要。
6.Java程序构建
名字可见性:C++引入“命名空间”概念,Java设计者鼓励程序员使用自己的Internet域名作为命名空间(域名很难重复)。java这种机制保证所有文件自动保存在自己的命名空间,而且每个类自动获得唯一的标识符(现在可以理解Eclipse打开类名时出现的一长串字母的含义了),语言已经帮你搞定命名重复问题。
如果在自己的程序里使用一个预定义好的类,编译器如何找到它?一种情况是那个类就定义在当前源文件中,只需直接引用即可,不用担心“向前引用”问题,即使它直到文件后面才定义。Java语言又帮你消除一个限制。另一种情况是(大部分情况)采用标准Java库的组件 ,他们与编译器配套:
import java.util.*; //使用* 通配符,可以不必要明确声明那个具体库
static关键字:如果设置了static关键字,数据或方法就不会同那个类的任何对象实例联系到一起。即使从未创建那个类对象,但仍能调用static方法或访问static数据。static的重要用途是确保在不创建对象的前提下调用类方法,特别是在定义程序运行入口方法main()的时候。
7.开始第一个Java程序
//:Property.java
import java.util.*;
/** The first Thinking in Java example program
* Lists system information on current machine.
* @author Bruce Eckel
* @author http://www.BruceEckel.com
* @version v1.0
*/
public class Property{
/** Sole entry point to class & application
* @param args array of string argus
* @return No return value
* @exception exceptions No exceptions thrown
*/
public static void main(String[] args){
System.out.println(new Date());
/**
* using Properties class in main function
*/
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());
try{
Thread.currentThread().sleep(5*1000);
} catch(InterruptedException e){}
}
} ///:end
需要注意的是:
(1)程序开头必须导入文件代码里用到的类(import),类库java.lang会自动导入。在网上http://tool.oschina.net/apidocs/apidoc?api=jdk_7u4 可以查找java API.
(2)如果是创建独立程序,文件中必须存在一个类与文件同名,而且类里必须包含一个名为main()的方法,形式如下:
public static void main(String[] args) //注意使用static修饰,自变量args不会在本程序用到,但必须列出,该变量保存了命令后调用的自变量。
(3)javadoc命令可以提取注释到html文件,具体参见http://www.cnblogs.com/bluestorm/archive/2012/10/04/2711329.html
(4)一个非正式的Java编程标准:大写类名的首字母,如果类名由几个单词组成,不能使用下划线,且每个单词首字母大写。例如:
class AllTheColorsOfTheRainbow {
int anIntegerRepresentingColors;
void changeTheHueOfTheColor(int newHue) {
// ...
}
// ...
}