Think in Java - Chatpter 2 一切都是对象

保存到什么地方?

  1. 寄存器 - 最快的保存区域,位于处理器内部(寄存器的数量十分有限,所以寄存器是根据需要由编译器分配 - 对此没有直接的控制权,不可能在自己的程序里找到寄存器存在的任何踪迹)
  2. 堆栈 - 驻留于常规RAM(随机访问存储器)区域,堆栈指针若向下移,会创建新的内存,向上移动,则会释放那些内存。(仅次于寄存器,是一种特别快,特别有效的数据保存方式)Java编译器必须准确知道堆栈内保存的所有数据的“长度”以及“存在时间”。这是由于它必须生成相应的代码,以便向上和向下移动指针。这一限制无疑影响了程序的灵活性,所以尽管有些Java数据保存在堆栈里 - 特别是对象的句柄,但是Java对象并不放在其中
  3. 堆 - 一种常规用途的内存池(也在RAM区域),其中保存了Java对象。 和堆栈不同,“堆heap”最吸引人的地方:在于编译器不必知道要从堆里分配多少存储空间,也不必知道存储的数据要在堆里停留多长的时间。(用堆保存数据时会有很大的灵活性 - 要求创建一个对象时,只需要new命令编写相关的代码即可 - 执行这些代码会在堆中自动进行数据的保存。为了达到这种灵活性,必然付出一些代价,在堆里分配存储空间时会花更长的时间)
  4. 静态存储 - 这儿的“静态”是指“位于固定位置”(尽然也在RAM里)。程序运行期间,静态存储的数据将随时等候调用。可用static关键字指出一个对象的特定元素是静态的,但Java对象本身永远不会置入静态存储空间
  5. 常数存储 - 常数值通常直接置于程序代码内部。这样做是安全的,因为他们永远都不会改变。有的常数需要严格地保护,所以可考虑将他们置于只读存储器ROM
  6. 非RAM存储 - 数据完全独立于一个程序之外,则程序不运行期间仍可存在。(两个主要的例子:“流式对象”和“固定对象”) - 它们能存在于其他媒体中,一旦需要,甚至能将他们恢复成普通的、基于RAM的对象
  • 流式对象 - 对象会变成字节流,通常发给另一台机器
  • 固定对象 - 保存在磁盘中

特殊情况:主要类型

在程序设计时需要频繁使用它们。

之所以要特别对象,是由于用new创建对象(特别是小的,简单的变量)并不是非常有效,因为new将对象置于“堆”里。对于这些类型,Java采纳了与C和C++相同的方法。也就是说,不是用new创建变量,而是创建一个并非句柄的“自动”变量。这个变量容纳了具体的值,并置于堆栈中,能够更高效地存取。

 

能对int和float做的事情,对BigInteger和BigDecimal一样可以做。

只是必须使用方法调用,不能使用运算符。

 

Java 数组,可以保证被初始化,而且不可在它范围之外访问。

创建数组 - 实际创建的是一个句柄数据。

每个句柄数据会自动初始化一个特殊值,并带有自己的关键字null;一旦Java看到null,就知道该句柄并未指向一个对象,正是使用前必须为每个句柄分配一个对象。

 

Java如何帮我们完成所有的清除工作:

// 作用域 - 对于在作用域里定义的名字,作用域同时决定了:可见性和存在时间
// 在C C++ Java里,作用域是由花括号的位置决定的
{
   int x = 12;
   /*only x available*/
   {
      int q = 96;
      /*both x & q available*/
   }
   /*only x available*/
   /*q out of scope*/
}

{
   String s = new String("a string");
}
/**
句柄S会在作用域的终点处消失,然而,S指向的Sring对象依然占据着内存空间。
结果:对于用new创建的对象,只要我们愿意,它们就会一直保留下去。这个编程问题在C和C++里特别突出。
Java有一个特别的“垃圾收集器”,会自动查找用new创建的所有对象,并辨别其中哪些不在被引用。
随后,它会自动释放由那些闲置对象占据的内存,以便能由新对象使用。
*/

 

 默认值

若某个主数据类型属于一个类成员,那么即使不明确(显式)进行初始化,也可以保证它们获得一个默认值。

  • Boolen   fasle
  • Char   ‘\u0000’ (null)
  • byte   (byte)0
  • short   (short)0
  • int   0
  • long   0L
  • float   0.0f
  • double   0.0d

这种保证并不适用于“局部”变量 -- 那些变量并非一个类的字段。

所以,假若在一个函数定义中写 

int = x;

那么x会得到一些随机值(这些和C C++是一样的),不会自动初始化为零。如果忘记,就会得到一条编译期错误,告诉我们变量可能尚未初始化。

 

 static关键字

  • 只想用一个存储区域来保存一个特定的数据 - 无论要创建多少个对象,甚至根本不创建对象
  • 需要一个特殊的方法,没有与这个类的任何对象关联
/**
一旦将什么东西设为static,数据或方法就不会同那个类的任何对象实例联系到一起。
所以尽管从未创建那个类的一个对象,仍能调用一个 static方法,或访问一些 static数据。
*/
class StaticTest { 
   Static int i = 47; 
} 
/**
现在,尽管我们制作了两个StaticTest 对象,但它们仍然只占据StaticTest.i的一个存储空间。
这两个对象都共享同样的i。请考察下述代码: 
此时,无论 st1.i还是st2.i都有同样的值47,因为它们引用的是同样的内存区域。
*/
StaticTest st1 = new StaticTest(); 
StaticTest st2 = new StaticTest(); 

 

一个特殊的类库会自动导入每个Java 文件:java.lang。

由于 java.lang 默认进入每个Java 代码文件,所以这些类在任何时候都可直接使用。

在这个列表里,可发现System和Runtime,我们在Property.java 里用到了它们。

 

注释和嵌入文档

 

1. 传统的C语言风格注释,是从C++继承而来的
/*这是
*一段注释
*它跨越了多个行
*/
但请记住,进行编译时,/*和*/之间的所有东西都会被忽略。
2. 第二种类型的注释也起源于C++。这种注释叫作“单行注释”,以一个“//”起头,表示这一行的所有内容都是注释。
// 这是一条单行注释

将代码同文档“链接”起来。

为达到这个目的,最简单的方法是将所有内容都置于同一个文件。

然而,为使一切都整齐划一,还必须使用一种特殊的注释语法,以便标记出特殊的文档;另外还需要一个工具,用于提取这些注释,并按有价值的形式将其展现出来。这些都是Java 必须做到的。 

/** 一个类注释 */ 
public class docTest { 
   /** 一个变量注释 */ 
   public int i; 
   /** 一个方法注释 */ 
   public void f() {} 
} 

// 嵌入式的HTML
/** 
* <pre> 
* System.out.println(new Date()); 
* </pre> 
*/ 
// 亦可象在其他Web文档里那样运用HTML,对普通文本进行格式化,使其更具条理、更加美观: 
/**
* 您<em>甚至</em>可以插入一个列表: 
* <ol> 
* <li> 项目一 
* <li> 项目二 
* <li> 项目三 
* </ol> 
*/

注意在文档注释中,位于一行最开头的星号会被javadoc 丢弃。同时丢弃的还有前导空格。

--------------------------------
// @see :引用其他类
所有三种类型的注释文档都可包含@see 标记,它允许我们引用其他类里的文档。对于这个标记,javadoc会生成相应的 HTML,将其直接链接到其他文档。格式如下:
@see 类名 
@see 完整类名 
@see 完整类名#方法名 
每一格式都会在生成的文档里自动加入一个超链接的“See Also”(参见)条目。

--------------------------------
// 类文档标记
类文档还可以包括用于版本信息以及作者姓名的标记
@version 版本信息
@author 作者信息
@param 参数名 说明
@return 说明
@exception 完整类名 说明 

@deprecated 
这是Java 1.1 的新特性。该标记用于指出一些旧功能已由改进过的新功能取代。该标记的作用是建议用户不必再使用一种特定的功能,因为未来改版时可能摒弃这一功能。若将一个方法标记为@deprecated,则使用该方法时会收到编译器的警告。

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值