如果我们说另一种不同的语言,那么我们就会发觉一个有些不同的世界"---路德维希·维特根斯坦(20世纪最有影响力的哲学家之一)
尽管Java是基于C++的,但是相比之下,Java是一种更“纯粹”的面向对象程序设计语言
本章将看到Java程序的基本组成部分,并体会到Java(几乎)一切都是对象
2.1 用引用操纵对象
操纵对象标识符实际上是操纵对象的一个“引用”,例如:操纵一个字符串,则可以创建一个String 引用
String s;
如果创建的只是引用而没有和任何事物关联,此时向s发送一个消息,就会返回一个运行时错误。安全的做法是
String s = "hello world";
2.2 必须由你创建所有对象
-
2.21 储存到什么地方
1)寄存器。在处理器内部处理速度最快但数量极其有限。你不能直接控制,也不能在程序中感觉到寄存器存在的任何迹象。2)堆栈。位于通用RAM中,但通过它的“堆栈指针”可以从处理器哪里获得支持。堆栈指针若向下移动,则分配新的内存;若向上移动,则释放那些内存。这是一种快速有效的分配存储方法,仅次于寄存器。创建程序时候,JAVA编译器必须知道存储在堆栈内所有数据的确切大小和生命周期,因为它必须生成相应的代码,以便上下移动堆栈指针。这一约束限制了程序的灵活性,所以虽然某些JAVA数据存储在堆栈中——特别是对象引用,但是JAVA对象不存储其中。
3)堆。一种通用性的内存池(也存在于RAM中),用于存放所有的JAVA对象。堆不同于堆栈的好处是:编译器不需要知道要从堆里分配多少存储区域,也不必知道存储的数据在堆里存活多长时间。因此,在堆里分配存储有很大的灵活性。当你需要创建一个对象的时候,只需要new写一行简单的代码,当执行这行代码时,会自动在堆里进行存储分配。当然,为这种灵活性必须要付出相应的代码。用堆进行存储分配比用堆栈进行存储存储需要更多的时间。
4)常量存储。常量值通常直接存放在程序代码内部,这样做是安全的,因为它们永远不会被改变。有时,在嵌入式系统中,常量本身会和其他部分分割离开,所以在这种情况下,可以选择将其放在ROM中。
5)非RAM存储。如果数据完全存活于程序之外,那么它可以不受程序的任何控制,在程序没有运行时也可以存在。
- 2.2.2 特例:基本类型 (不是引用的自动变量 值存于堆栈中 更高效)
基本类型 | 大小 | 最小值 | 最大值 | 包装器类型 |
---|---|---|---|---|
boolean | - | - | - | Boolean |
char | -bit | Unicode | Unicode-1 | Character |
byte | bits | Byte | ||
short | bits | -1 | Short | |
int | bits | -1 | Integer | |
long | bits | -1 | Long | |
float | bits | IEEE754 | IEEE754 | Float |
double | bits | IEEE754 | IEEE754 | Double |
void | - | - | - | Void |
- 2.2.3 Java中的数组
当创建一个数组对象时,实际上创建了一个引用数组,并且每个引用都会自动被初始化一个的定值,该值拥有自己的关键字null.一旦Java看到null,就知道这个引用还没有指向某个对象。在使用任何引用对象前,必须为其指定一个对象
2.3 永远不要销毁对象
- 2.3.1 作用域(scope)
作用域定义了在其内定义的变量名的可见性和生命周期,作用域由花括号的位置决定
{
int x = 520; // x 可见
{
int q = 250; //x,q 可见
}
// x 可见
// q 生命周期结束
}
// x 生命周期结束
- 2.3.2 对象的作用域
Java对象不具备和基本类型一样的生命周期,当用new一个Java对象时,它可以存活于作用域之外。
{
String s = new String("I Love You");
}
引用s 在作用域终点就消失了。然而,s指向的String对象仍然占据内存空间,在这之后无法访问这个对象,事实上,由new创建的对象,只要你需要,一直会保留下去。然而Java有一个垃圾回收器,用来监视用new所创建的对象,并辨别哪些不会在被引用的对象,随后释放这些对象的内存空间,以便其他新的对象使用。(消除内存泄漏问题)
2.4 创建新的数据类型:类 (class)
- 2.4.1 字段和方法
在Java中你所做的全部工作就是定义类,产生哪些类的对象,以及发送消息给这些对象
基本成员默认值
基本类型 | 默认值 |
---|---|
() | |
2.5 方法、参数和返回
Java的方法决定了一个对象能就收什么消息。方法的基本组成包括:名称、参数、返回值和方法体。
{
ReturnType methodName(//参数)
//方法体
}
方法名和参数列表合起来被称为”方法签名“ 唯一标识某个方法
假如一个被实力化的a对象 中有方法f()返回类型为 int,调用
int x = a.f();
这种调用方法的行为通常被称为发送消息给对象。消息是f(),对象是a,面向对象的设计简单归纳为”向对象发送消息“;
2.5.1 参数列表
方法的参数列表制定要传递给方法什么样的信息。
2.6 构建一个java 程序
2.6.1 名字可见性
防止由于命名重复发生模块冲突,采用反转域名对目录划分。
这种机制意味着所有的文件都能够自动存活于他们自己的命名空间,同一个文件内的每个类哦都有唯一的标识符。2.6.2 运用其他构件
如果自己的程序中使用预先定义好的类,使用关键字import来准确地告诉编译器你想要的类是什么。import指示编译器导入一个包,也就是一个类库
import java.util.*;
- 2.6.3 static 关键字
通常来说,当创建类时,就是描述那个类的外观行为。除非用new来创建那个类的对象,否则,实际上并未获得任何对象。执行new来创建对象时,数据存储空间才被分配,其方法才被外界调用。
有两种情形用上述方法是无法解决的,一种情形是,只想为特定域分配单一存储空间,而不去考虑究竟要创建多少对象,甚至根本不创建对象。另一种情形是,希望某个方法不与包含它的类任何对象关联在一起。也就是说,即使没有创建对象,也能够调用这个方法。
通过static可以满足这两个方面需求。当声明一个事物是static时,就意味这这个域或方法不会与包含它的那个类的任何对象实例关联在一起。所以,即使从未创建任何类的对象,也可以调用static方法或访问static域,通常,你必须创建一个对象,并用它来访问数据或方法。因为非static域和方法必须知道它们一起运作的对象。
有些面向对象语言采用类数据和类方法这个术语,代表哪些数据和方法只是作为整个类,而不是类的某个特定对象而存在的,有时,一些Java文献里也用到这两个术语。
只须将static关键字放在定义之前,就可以将字段或方法设定为static,例如,下面的代码就生成了一个static字段,并对其进行初始化
class StaticTestP{
static int i = 47;
}
现在,即使你创建了两个StaticTest对象,StaticTest.i也只有一份存储空间,这两个对象共享一个i,再看看下面的代码
StaticTest st1 = new StaticTest();
StaticTest st2 = new StaticTest();
在这里,st1.i和st2.i只想同一存储空间,因此他们具有相同的值。
引用static变量有两种方法。可以通过对象去定位它,另一种是通过类名直接引用
使用类名是引用static变量的首选方法,这不仅因为它强调变量的static结构,而且在某些情况下它还为编译器进行优化提供好的机会。
当static作用于某个字段是,会改变数据创建的方式(因为static字段对每个类来说都只有一份存储空间,而非static字段则是对每个对象有一个存储空间),但static作用于某个方法,差别没那么大,stataic方法重要作用在不创建对象的前提下就可以调用它,例如main()方法。
2.7 你的第一个Java程序
import java.util.*
public class HelloDate{
public static void main(String[] args){
System.out.println("Hello,it's");
System.out.prontln(new Date);
}
}
在每个程序的开头必须声明import语句,引入文件代码所需要的类。(java.lang会被自动导入到每个java文件中)
类名必须和文件名相同,如果你像现在这样创建一个独立运行的程序,文件中必须存在某个类与该文件名相同(否则,编译报错),且那个类必须包含一个名为main()的方法。
public static void main(String[] args)
其中,public关键字是一个可由外部调用的方法。main()方法的参数是一个String对象的数组,这个程序并未用到args,但Java编译器必须要求这样做,因为args要用来存储命令行参数。
Sytem.out.print(new Date());
在这里传递的参数是一个Date对象,一旦创建之后就可以直接将他的值发送给println()(它被自动转换为String类型)。当这条语句执行完后,Date对象就不再被使用,而垃圾回收器会发现这一情况,并在任意时候将其回收。因此我们没必要去关心怎样清理它。
2.7.1 编译和运行
要编译运行程序,必须要有Java开发环境。安装sun提供的JDK ,JDK安装好后,需要设定路径信息,确保计算机可以找到javac和java这两个文件。
2.8 注释和嵌入式文档
以/*开始 可跨越多行以 */结束
单行 //
编译时会被忽略
2.9 代码风格
驼峰风格