首页 > 代码库 > JAVA编程思想(1) - 一切都是对象

JAVA编程思想(1) - 一切都是对象

 -“如果我们说另一种不用的语言,那么我们就会发觉一个有些不同的世界”


1. 用引用操纵对象

       每种编程语言都有自己的数据处理方式。有些时候,程序员必须时刻留意准备处理的是什么类型。您曾利用一些特殊语法直接操作过对象,或处理过一些间接表示的对象吗(C或C++里的指针)?

所有的这一切在JAVA里都得到了简化。在JAVA里一切都被视为对象,尽管是一切都被看成对象,但操纵的标识符实际上是一个“引用”而已,简单来说是:对象好比”电视“,我们拥有的引用是"遥控器",因此我们即使没有对象的真实存在,我们也可以拥有引用,也就说你可以拥有一个引用,而它并不需要和一个对象关联

如: String s;   

我们这里创建的只是引用,并不是对象,如果此时向s发送一个消息,就会返回一个运行错误,因为没有真正的对象与它关联,因此一个安全的做法是:创建一个引用同时进行初始化。

如: String s = "haha";

这里用到了Java语言的一个特性:字符串可以用带引号的文本初始化,通常,必须对“对象”采用一种更通用的初始化方法。


2. 必须由你创建所有的对象

(1) 一旦创建一个引用,就希望它能与一个新的对象相关联。通常用new操作符来实现这一目的。

如: String s = new String("haha");

----------------------------------------------------------------------------------------------------------------------------------------------------

(2) 程序运行时,有五个不同的地方可以储存数据

-寄存器:这是最快的存储区,因为它位于不同于其他储存区的地方——处理器内部。但是数量有限,所以需要进行分配。无法直接控制(另一方面,C和C++允许你向编译器建议寄存器的分配方式)

-堆栈:位于通用RAM(随机访问存储器)中,但通过堆栈指针可以从处理器那里获得直接的支持。堆栈指针若向下移动,则分配新的内存;若向上移动,则释放那些内存。分配储存方式效率仅次于寄存器

-堆:一种通用的内存池(也位于RAM),用于存放所有的对象。堆不同于堆栈的好处是:编译器不需要知道存储的数据在堆里存活多长时间。因此有更多的灵活性,可以方便创建对象。但是因此付出的代价是:用堆进行存储分配和清理可以比用堆栈分配更需要时间(如果确实可以在Java中像在C++一样在栈中创建对象)

-常量存储:常量值通常直接存放在程序代码内部,这样做很安全,因为它永远不会被改变

-非RAM存储:如果数据完全存活在程序之外,那么它可以不受程序的任何控制,在程序没有运行时也可以存在。其中两个基本的例子是流对象和持久对象。在流对象中,对象转化成字节流,通常被发送到另一台机器。在持久化对象中,对象被存放在磁盘上,因此即使程序终止了,它们仍然保持自己的状态。正如Java提供的对轻量级持久化的支持

----------------------------------------------------------------------------------------------------------------------------------------------------

(3) 特例:基本类型

-在程序设计中经常用到一系列类型,它们需要特殊对待,可以把他们想象成“基本”类型。之所以特殊对待,是因为new将对象存储在“堆”里,故用new创建一个对象——特别是小的,简单的变量。往往不是很有效。因此,对于这些类型,Java采用和C和C++相同的方法,也就是不用new来创建变量,而是创建一个并非是引用的“自动”变量。这个变量直接存储“值”并置于堆栈中,因此更加有效

-Java要确定每种基本类型所占存储空间的大小,它们的大小并不像其他大多数语言那样随机器硬件架构的变化而变化这种所占空间大小的不变性是Java程序比其它大多数语言编写的程序更具可移植性的原因之一。

----------------------------------------------------------------------------------------------------------------------------------------------------

(3) Java中的数组

-几乎所有的程序设计语言都支持数组,在C和C++中使用数组是危险的,因为C和C++中数组就是内存快。如果一个程序要访问其内存块之外的数组,或在数组初始化前使用内存,都会产生难以预料的后果。

-Java的主要目标之一是安全,所以Java确保数组会被初始化,而且不能在它的范围之外被访问。这种范围检查,是以每个数组上少量的内存开销及运行时的下标检查为代价换来安全性和效率的提高。

-当创建一个数组对象时,实际上就是创建一个引用数组,而且每个引用都会自动被初始化为一个特定值,该值拥有自己的关键字null。一旦Java看到null,就知道这个引用还没有指向某个对象,试图使用一个null引用是会造成运行错误的。对于基本类型的数组,Java会为这种数组所占的内存全部置0


3. 永远不需要销毁对象

-大多数的程序设计语言中,变量的生命周期的概念,占据了程序设计工作中非常重要的部分。

(1) 作用域

作用域决定了在其内定义的变量名的可见性和生命周期。在C和C++以及Java中,作用域由花括号决定的。

{
    int x = 12;
    // only x available
    {
         int q = 36;
         //both x & q available
    }
    //only x available
    // q is "out of scope"
}
还有在Java中不允许重命名

{
    int x = 12;
    {
         int x = 96;   //  Illegal
     }
}
(2) 对象的作用域
Java对象不具备和基本类型一样的生命周期。当用new创建一个对象时,它可以存活于作用域之外

{
    String s = new String("a string");
} // End of scope
引用s在作用域终点就消失了。然后,s指向的String对象仍继续占用内存空间。我们无法在作用域之后访问消失的对象引用。

-事实证明,由new创建的对象,只要你需要,就会一直保留下去。这样,许多C++编程问题在Java就完全消失了。我们不必在像在C++一样:实时关注我们的对象。在Java中有一个“垃圾回收器”来监视用new创建的对象,一旦不再需要了,它们就会被回收。这样做就消除了这类编程问题(即:内存泄露)。