java编程思想学习日志——一切都是对象

来源:互联网 发布:机械三维设计软件排名 编辑:程序博客网 时间:2024/06/01 10:25

尽管Java是基于C++的,但是相比之下,Java是一种更“纯粹”的面向对象程序设计语言。Java语言假设我们只进行面向对象的程序设计。也就是说,在开始用Java进行设计之前,必须将思想转换到面向对象的世界中来。在本章,我们将看到Java程序的基本组成部分,并体会到在Java中(几乎)一切都是对象。

1.创建对象

每种编程语言都有自己的操纵内存中元素的方式。在Java中,一切都被视为对象,因此可采用单一固定的语法。操纵的标识符实际上是对象的一个“引用”(reference),想操纵一个词或句子,可以创建一个String引用:String s;

但这里所创建的只是引用,并不是对象。如果此时向s发送一个消息,就会返回一个运行时错误,因为此时s实际上没有与任何事物相关联。因此,一种安全的做法是:创建一个引用的同时便进行初始化String s = "asdf";
这里用到的是Java语言的一个特性:字符串可以用带引号的文本初始化。通常,必须对对象采用一种更通用的初始化方法:String s = new String("asdf");
new表示的是“给我一个新对象”。上述语句表示通过提供一个初始字符串,给出了怎样产生这个String的信息。

Java提供了大量过剩的现成类型。重要的是,你可以自行创建类型,这是Java程序设计中的一项基本行为

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

  1. 寄存器 最快的存储区位于处理器内部但是数量极为有限,所以要根据需求进行分配,不能直接控制,也不能在程序中感觉到寄存器存在的任何迹象(但是由于C和C++允许您向编译器建议寄存器的分配方式)。
  2. 堆栈 位于通用RAM(随机访问存储器)中,但通过堆栈指针可以从处理器那里获得直接支持。堆栈指针向下移动分配新内存。向上移动释放内存。这是仅次于寄存器的最有效的存储方法。Java系统必须在创建程序时知道存储在堆栈内所有项的确切生命周期,以便上下移动堆栈指针,这一约束限制了程序的灵活性,所以虽然某些Java数据存储于堆栈中(特别是对象引用),但是Java对象并不存储于其中。
  3. 一种通用的内存池(位于RAM),用于存放所有的Java对象。堆不同于堆栈的好处是:编译器不需要知道存储的数据在堆里存活多长时间。因此,在堆里分配存储有很大的灵活性。当需要一个对象时,只需用new写一行简单的代码,当执行这行代码是,会自动在堆里进行存储分配。当然,这种灵活性要付出相应的代价:用堆进行存储分配和清理可能比用堆栈进行存储分配需要更多的时间
  4. 常量存储 常量值通常直接存放在程序代码内部,这样做是安全的,因为他们永远不会被改变。有时,在嵌入式系统中,常量本身会和其它部分隔离开,所以在这种情况下,可以选择将其存放在ROM(只读存储器)中。
  5. 非RAM存储 数据完全存活于程序之外,不受程序控制,在程序没有运行时也可以存在。其中两个基本的例子就是流对象持久化对象。在流对象中,对象转化成字节流,通常被发送给另一台机器。在持久化对象中,对象被存放于磁盘上,因此,即使程序终止,他们仍可以保持自己的状态。这种存储方式的技巧在于:把对象转化成可以存放在其他媒介上的事物,在需要时,可恢复成常规的、基于RAM的对象。Java提供了对轻量级持久化的支持, 而诸如JDBC和hibernate这样的机制提供了更加复杂的对在数据库中存储和读取对象信息的支持。

2.基本类型

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

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

基本类型 大小 最小值 最大值 包装器类型 boolean – – – Boolean char 16-bit Unicode 0 Unicode 216 -1 Character byte 8 bits -128 +127 Byte short 16 bits -215 +215 -1 Short int 32 bits -231 +231 -1 Integer long 64 bits -263 +263 -1 Long float 32 bits IEEE754 IEEE754 Float double 64 bits IEEE754 IEEE754 Double void – – – Void

boolean类型所占存储空间的大小没有明确指定,所有数值类型都有正负号,所以不要去寻找无符号的数值类型。
基本类型具有的包装器类,使得可以在堆中创建一个非基本对象,例如:

char c = "x";Character ch = new Character(c);

或者

Character ch = new Character("x");

也可以反向转换

Character ch = "x";char c = ch;

Java提供了两个高精度计算的类:BigIntegerBigDecimal。虽然它们大体上属于“包装器类”的范畴,但二者都没有对应的基本类型。不过这两个类包含的方法,提供的操作与对基本类型所能执行的操作类似。也就是说能作用于int和float的操作,也同样能作用于BigInteger和BigDecimal。只不过必须以方法调用方式取代运算符方式来实现,运算速度会比较慢。这里我们用速度换取了精度

关于数组,Java确保数组会被初始化,而且不能在它的范围之外被访问。这种范围检查,是以每个数组上少量的内存开销及运行时的下标检查为代价的。但由此换来的是安全性和效率的提高,而且这种操作有时可以被优化

Java对象不具备和基本类型一样的生命周期。当用new创建一个Java对象时,它可以存活于作用域之外,但在Java里不允许已定义过的变量:

{    int x = 12;    {        int x  = 23;//这种代码在C和C++中是合法的,但Java中不允许    }}

同样,我们可以在作用域之内的任何空间使用这些已定义的变量,在Java中由new创建的对象,只要你需要,就会一直保留下去。而Java的垃圾回收器则会监视由new创建的所有对象,并辨别那些不会再被引用的对象。随后,释放这些对象的内存空间,以便供其他新的对象使用,所以你不必担心内存回收的问题,消除了内存泄漏的问题

在Java中你所做的全部工作就是定义类,产生那些类的对象,以及发送消息给这些对象。一旦定义了一个类,就可以在类中设置两种类型的元素:字段(数据成员)和方法(成员函数)。字段可以是任何类型的对象,也可以是基本类型中的一种。如果字段是某个对象的引用,那么必须初始化该引用,以便使其与一个实际的对象相关联。

每个对象都有用来存储其字段的空间;普通字段不能在对象间共享。
在你创建了一个可以存储对象的类后,你可以在对象引用的名称之后紧接着一个句点,然后接上对象内部成员名称来给其赋值,比如:

Class DataOnly{    int i;    double d;    boolean b;}DataOnly dn1 = new DataOnly();dn.i = 1;dn.d = 1.1;dn.b = false;

若类的某个成员是基本数据类型,即使没有进行初始化,Java也会确保他获得一个默认值,如下表

基本类型 默认值 boolean false char ‘\uoooo’(null) byte (byte)0 short (short)0 int 0 long 0L float 0.0f double 0.0d

当变量作为类的成员使用,Java才会确保他的默认值,但是这些初始值对你的程序来说可能是不合法的,所以最好明确地对变量进行初始化
但是这种初始化并不适用于局部变量,比如某方法定义中有int x;那么变量x得到的可能是任意值,而不会被自动初始化为零。如果没有被赋值,Java会在编译时返回错误。

3.构建java程序

Java的方法决定了一个对象能够接收什么样的消息。基本组成部分包括:名称、参数、返回值和方法体。返回类型描述的是在调用方法之后从方法返回的值。参数列表给出了要传给方法的信息的类型和名称。方法名和参数列表唯一地标识出某个方法。

Java中的方法只能作为类的一部分来创建。方法只有通过对象才能被调用,且这个对象必须能执行这个方法调用。通过对象调用方法时,需要先列出对象名,紧接着是句点,然后是方法名和参数列表。如objectName.methodName(arg1,arg2,arg3);假设有一个方法f(),不带任何参数,返回类型是int。如果有个名为a的对象,可以通过他调用f(),那么就可以写成: int x = a.f(); 返回型类型必须要与x的类型兼容。
这种调用方法的行为通常被称为发送消息给对象。在上面的例子中,消息是f(),对象是a。面向对象的程序设计通常简单地归纳为“向对象发送消息”。
最基本的程序只是一系列带有方法的对象集合,这些方法以其他的对象为参数,并发送消息给其他对象。

static关键字:当声明一个事物是static时,就意味着这个域或方法不会与包含它的那个类的任何对象实例关联在一起。所以,即使从未创建某个类的任何对象,也可以调用其static方法或访问其static域。通常,你必须创建一个对象,并用它来访问数据或方法。因为非static域和方法必须知道他们一起运作的特定对象。只须将static关键字放在定义之前,就可以将字段或方法设定为static。
使用类名是引用static变量的首选方式,这不仅是因为他强调了变量的static结构,而且在某些情况下它还为编译器进行优化提供了更好的机会。类似逻辑也应用与静态方法。

类的名字必须和文件名相同。如果创建一个独立运行的程序,那么文件中必须存在某个类与该文件同名,且那个类必须包含一个名为main()的方法。main()方法的参数是一个String对象的数组,args要用来存储命令行参数

在“Java编程语言编码约定”中,代码风格是这样规定的:类名的首字母要大写;如果类名由几个单词构成,那么把它们并在一起,其中每个内部单词的首字母都采用大写形式。方法、成员变量以及对象引用名称等都与类风格一样,但是标识符的第一个字母采用小写

阅读全文
0 0