-
Notifications
You must be signed in to change notification settings - Fork 44
/
02 第二章.java
195 lines (179 loc) · 13 KB
/
02 第二章.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
import code_list_one.*;
import java.util.Date;
public class 第二章 {
/*
* ·第二章:一切都是对象
*
* ·在java中一切都被视为对象,因此可采用单一固定的语法。尽管一切都看成对象,但操纵的标识符实际上是对象的一个"引用"。
* 可以将此情形想象为"遥控器"(引用)与"电视机"(对象),只要握住这个遥控器,就能保持与电视机连接.
* 当想减少音量,实际操控的是"遥控器"(引用),在由遥控器来控制"电视机"(对象)
* 如果你想在房间里面到处走走,同时可以控制"电视机",那么只需要携带"遥控器"(引用),而不是电视机(对象)
* ·此外,即使没有电视机,遥控器也可以独立存在,也就是说,你拥有一个引用,并不一定需要有一个对象与它关联。像这样创建一个引用:String s;
* 但这里创建非只是引用,并不是对象。如果这是向s发送一个消息,就会返回一个运行时的 错误。因为这会s实际并没有与任何事物关联
*
*
* ·必须由你创建所有对象
* ·存储到什么地方
* ·程序运行时,对象是怎么进行放置安排的呢?特别是内存是怎样分配的呢?有五个地方可以存储数据(java程序中的数据可能存储到的五个区域)
* ·寄存器。这是最快的存储区,因为它位于不同于其他存储区的地方--处理去内部。但是寄存器的数量极其有限,所以寄存器根据需求进行分配。
* 你不能控制,也不能在程序中感觉到寄存器存在的任何迹象(另一方面,C/C++允许您向编译器建议寄存器的分配地址)
* ·堆栈。位于通用RAM(随机访问存储器)中,但是通过堆栈指针可以从处理器那里获得直接的支持。堆栈指针向下移动,则分配新的内存,向上移动,则释放那些内存。
* 这是一种快速有效的分配存储的方法,仅次于寄存器。创建程序时,java系统必须知道存储在堆栈内所有项确切的生命周期,以便上下移动堆栈指针。这一约束限制了程序的灵活性,
* 所以虽然某些java数据存储于堆栈中--特别是对象引用,但是java对象并不存储于其中
* ·堆。一种通用的内存池(也位于RAM区),用于存放所有的java对象。堆不同于 堆栈 的好处是:编译器不需要知道存储的数据在堆里存活的时间。因此在堆中分配存储有很大的灵活性。
* 当需要一个对象是,只需要new写一行简单的带代码,当执行这行代码的时候,会自动在对 堆 中进行存储分配。
* 当然,为了这种灵活性是要付出代价的:用 堆 进行存储分配和清理比在 堆栈(栈) 中更耗时。(c/c++可以在 栈 中分配内存,但是java不行)
* ·常量存储。常量值通常直接存放在程序代码内部,这样做是安全的。因为它们永远不会被改变
* ·非RAM存储。 如果数据完全存活于程序之外,那么它可以不受程序的任何控制,在程序没有运行时也可以存在。其中两个基本的例子是 流对象 和 持久化对象。
* ·在流对象中,对象转化成字节流,通常被发送给另一台机器。
* ·在"持久化对象"中,对象被存储在磁盘上,因此,程序被终结,它们也可以保持自己的状态。
* 这种存储方式的技巧在于:把对象转化为可以存放在其他媒介上的事物,在需要时,可恢复成常规,基于RAM的对象。
* java提供轻量级持久化的支持,而想jdbc和hibernate这样的机制提供了更加复杂的。
* ·特例:基本类型(不用由你创建的对象)
* ·为什么不用你创建:在程序设计中经常用到一系列类型,它们需要特殊的对待(因为如果自己new的话,会在 堆 中存储这,这样的话聚会耗时),但是你会经常使用这些数据,所以要特殊对待
* 是因为new将对象存储在"堆"里,故用new创建一个对象--一个特别小简单的变量,往往不是很有效(如果你打算把一个数字 1 new进去的话)
* 因此,对于这些类型(比较简单的),java采取C/C++相同的方法。也就是说,不用new来创建变量,而是创建一个并非是引用的变量(就是操作这个变量是不用引用的,就是不用通过遥控器进行操作)。
* 这个变量直接存储"值",并置于堆栈中,因此更加高效。
* ·boolean类型所占存储空间的大小没有明确指定,仅定义为能够取字面值true或false
* ·基本类型具有的包装类(包装类创建对象跟其他类是一样的,创建的一个非基本对象在 堆 中,而基本类型创建出来是在 堆栈 中的,而且是没有引用的)
* 例如:
* char c = 'x';
* Character ch = new Character(c);
* 也可以这样用:
* Character ch = new Character('x');
* java SE 5.0 的 自动包装功能 能将自动地将 基本类型 转换为 包装器类型(基本类型的数据在 堆栈 中, 包装器类型的数据在 堆 中)
* Character ch = 'x';
* 并可以反向转换
* char c = ch;
*
* ·高精度数字
* ·java提供两个用于高精度计算的BigInteger和BigDecimal.虽然它们大体上属于"包装器类"的范围,但二者都没有对应的基本类型
* 不过,这两个类包含的方法,提供的操作对 基本类型 所能执行的操作相似。也就是说,能作用于int或float的操作,也同样能够作用于这两个类上。
* 只不过是以方法调用的方式取代了运行符方式实现。由于这么做复杂了许多,所以运行速度会比较慢。在这里以精度换取了速度
* ·java中的数组
* 当创建一个数组对象时,实际上就是创建了一个引用数组,并且每个引用都会自动被初始化为一个特定值,该值拥有自己的关键字null。
* 一旦java看见null,就知道这个引用还没有指向某个对象。在使用任何引用之前,必须指定一个对象
* 如果使用一个还是null的引用,在运行时就会报错。
* 还可以创建用来存放基本类型的数组。同样,编译器也能确保这种数组的初始化,因为它会将这种数组初始化为0(基本类型没有引用)
*
*
* ·永远不要销毁对象
* ·作用域:作用域决定了在其内定义的变量名的可见性和生命周期,在C,C++,java中,作用域由花括号的位置决定的。例如:
* {
* int x = 12;
* {
* int y = 13;
* }
* }
* 在作用域定义的变量只可用于作用域结束之前。
* ·对象的作用域
* ·java对象不具备和基本类型一样额生命周期。当用new创建一个对象时,它就可以存活于作用域之外。例如:
* {
* String s = new String("a object");
* }
* 引用s在作用域的终点(也就是花括号结束,是一个引用消失,不是对象消失)就消失了。然而,s指向的对象还在内存区域中,我们也无法访问这个对象(因为对它唯一的引用已经超出了作用域范围)
* ·事实证明,由new创建的对象,只要你需要,就会一直保留下去。但这不会出现对象填满内存空间吗?(这是C++经常出现的问题)
* java有一个垃圾回收器,用来监视用new出来的对象,并辨别那些不会再被引用的对象,随后就会释放这些对象的内存空间。(所以你不用担心内存泄漏问题)
*
* ·基本成员默认值
* ·如果类的某个成员是基本数据类型,即使没有进行初始化,java也会确保它获得一个默认值。
* 当变量作为 类的成员变量 使用时,java才确保给定其默认值,以确保那些是基本类型的成员变量等到初始化,防止程序出错。
* 但是,这些初始化的值可能是你不想要的,甚至是不合法的,所以最好对变量进行初始化。
* ·注意:上述确保初始化的方法并不是适合于"局部"变量。所以,在某个方法定义中有:int x; 那么该变量等到的可能是任意值,而不会被自动初始化为零。
* 所以在使用x前,应先对其赋一个适当的值。如果没有这么做,那么编译时就会返回一个错误,告诉你变量没有初始化。(这正是java优于C++的原因,C++只被视为警告,而java视为错误)
*
* ·java中的方法只能作为类的一部分来创建,方法只有通过对象才能被调用。(除了static,static方法并不依赖于对象的存在 )
* ·方法名和参数列表 (被称为"方法签名") 唯一地标识出某个方法
* ·字段和方法:一旦定义了一个类,就可以在类中设置两种类型的元素:字段和方法
*
* ·static关键字:
* 通过static关键字可以满足下面两个方面的需要:
* ·只想为某特定域分配单一的存储空间,而不去考虑要创建多少对象,甚至根本不需要创建任何的对象
* ·希望某个方法不与这个类型的任何对象相关联
* 例如:static int i = 47;
* ·有些面向对象语言(一个java文献也用到这些术语)使用 类数据 和 类方法 两个术语 表示使用了static关键字的数据
*
*
* ·注释文档的语法
* ·共有三种类型的注释文档(类,域,方法 ),都是位于前面(例如 类注释 在 定义类之前 要定义)
* 类的注释写在这
* public class Document{
* 域的注释
* public int i;
* 方法的注释
* public void method(){}
* }
* ·注意:javadoc只能为public和protected成语进行文档注释。private会被忽略(非要可见的话可以使用-private注解)
*
* ·嵌入式HTML
* javadoc通过生成的HTML文档传送HTML命令,这使你能够充分利用HTML
*
* ·一些标签示例
* @see:引用其他类(在文档中是以一个超链接的形式导去另一个类中)
* @version:版本号
* @author:作者
* @since:最早使用的版本号
* @param:参数
* @return:描述返回值的类型
* @throws:对抛出的异常进行处理
* @deprecated:指出一些旧特征已由改进的新特征取代
*/
public static void main(String[] args) {
//java的基本类型数组 和 包装器类型数组
array();
/*
* 第一个java程序
* ·在每个程序的开头,必须声明import语句(每个java文件都默认导入java.lang)
* ·java.lang中没有Date类,所以必须导入另一个类库才能使用它
* ·选择java.lang,在选择System类.选择out字段,可以看见out是一个静态的PrintStream类型,因为是静态所以不需要创建任何东西,out对象就可以使用。
* 但是out对象可以做什么(调用什么方法),是由它的类型PrintStream决定的,直接看PrintStream里面有什么方法可用即可。
* PrintStream类中有一个println方法,可以将给你的数据打印到控制台
*
* 这里模拟main方法
*/
main();
/*
* static关键字
*/
staticWord();
/*
* 练习
*/
ObjectB objectB;
HelloData helloData;
ATypeName aTypeName;
DataOnly dataOnly;
ObjectC objectC;
Incrementable incrementable;
ObjectD objectD;
ObjectE objectE;
}
private static void array() {
int[] a = new int[8];
System.out.println("基本类型数组的初始化值是:" + a[0]);
/*
* 基本数据类型的数组的初始值是 0
* 基本数组类型的存储区域是 堆栈 (因为在这里的数据存储速度会很快,当你要经常使用这些数据的时候就会很方便)
*/
Integer[] b = new Integer[8];
System.out.println("包装器类型数组的初始化值是:" + b[0]);
/*
* 包装器类型的数组的初始值是 null
* 这是包装类型,数据的存储区域是 堆 中,(这里是与其他的对象一样的,就是存储时比存储在 堆栈 中的快)
*/
}
private static void main(){
System.out.println("Hello,it's:");
System.out.println(new Date());
System.getProperties().list(System.out);
}
public static void staticWord(){
ObjectA a1 = new ObjectA();
ObjectA a2 = new ObjectA();
System.out.println("对象a1的i值是" + a1.i);
System.out.println("对象a2的i值是" + a2.i);
ObjectA.i++;
System.out.println("对象a1将i值是" + a1.i);
System.out.println("对象a2中的i值" + a2.i);
}
}