Java编程思想读书笔记——第二章:一切都是对象
第二章 一切都是对象
尽管Java是基于C++的,但是相比之下,Java是一种更“纯粹”的面向对象程序设计语言。
在本章,我们将看到Java程序的基本组成部分,并体会到在Java中(几乎)一切都是对象。
2.1 用引用操纵对象
1、操纵的标识符实际上是对象的一个“引用”
2、书中用遥控器和电视机来形象的比喻:
- 要想调控电视机,只需携带遥控器,而不用携带电视机
- 即使没有电视机,遥控器也可以独立存在
- 如果没有电视机,却用遥控器调控电视机,那么就会返回一个运行时错误,我们常见的空指针
3、我们自己可以这么理解:
- 我和媳妇儿都持有同一张银行卡的引用,不管我们两人中的谁取了钱或者存了钱,两个人引用的这张卡的余额都会发生改变
- 如果我没有银行卡,却去操作银行卡取钱,那指定报错啊,连银行卡都没有取鸡毛钱
2.2 必须由你创建所有对象
通常用new操作符来实现这一目的
2.2.1 存储到什么地方
- 寄存器:最快的存储区,位于处理器内部,数量有限,我们在外部无法控制
- 堆栈:存放基本类型的数据和对象的引用,通过堆栈指针,向下移动分配新内存,向上移动释放内存
- 堆:用来存放new出来的对象和数组,由Java垃圾回收管理。需要一个对象就new一下,会自动在堆里进行存储分配
- 常量存储:通常存放在程序代码内部
- 非RAM存储:那就是外部存储了,比如磁盘上面的,用的时候转化过来
栈和堆的区分
- 栈中分配内存空间,作用域结束后这部分空间会被用作新的空间进行分配,更高效一些吧
- 堆中分配内存空间,作用域结束后不会回收,等待系统垃圾回收
2.2.2 特例:基本类型
- 放在堆里不是很高效,基本类型会存在栈中,不用new来创建,直接存储“值”,更加高效
- 每种基本类型所占存储空间的大小是不变的,这种不变性是Java更具可移植性的原因之一
- 基本类型具有的包装器类,让我们可以在堆中创建一个非基本对象,用来表示对应的基本类型
- 直接来一张图:
高精度数字提供了两个类:
- BigInteger和BigDecimal,能作用于int和float的操作,都可以作用于它们
- 但是必须以方法调用,所以使用速度换了精度
- 具体使用可以查看JDK文档,这里就不多说了
2.2.3 Java中的数组
Java确保数组会被初始化,用内存和下标检查换来了安全性和效率的提高,这里不介绍了,以后的章节会详细讨论数组的
2.3 永远不需要销毁对象
Java不需要考虑变量的生命周期,也就是它可以自动进行垃圾回收
2.3.1 作用域
花括号就是一个作用域,注意和C++的区分,这样的代码在Java中是不允许的,Java的设计者会认为这样会导致程序混乱:
{ int x = 1; { int x = 2; } }
2.3.2 对象的作用域
- 由new创建的对象,只要你需要就会一直存在,你不需要了就会被垃圾回收器回收,防止“内存泄漏”
- 而C++中呢,你得确保对象的保留时间和你需要此对象的时间一样长,在使用完它们后,手动进行销毁
2.4 创建新的数据类型:类
类用class来表示,这样就引入了一种新的类型
2.4.1 字段和方法
- 类中包含了两种类型的元素,字段和方法,这个不用多说了吧
- 基本类型的默认值,基本类型即使没有初始化也会有一个默认值,这个默认值只适用于成员变量,局部变量不好使
- 其实说实话开发中常用的要记住的默认值还是int,boolean,String这三种
- 直接来一张图:
2.5 方法、参数和返回值
- 其实我还是喜欢称之为“方法”,而不是“函数”,尽管它们都是一个意思,哈哈哈
- 方法包括:方法名、参数、方法体、返回值
- 方法名和参数列表合起来能唯一的标识出某个方法,这里就涉及到了方法的重载
- 调用方法在此书中被称为“向对象发送消息”
2.5.1 参数列表
- 参数列表指定要传递给方法什么样的信息
- return 关键字的用法,表示“已经做完”,要离开此方法
- 如果不想返回任何值,那么可以指定返回类型为void,在方法的任何地方都可以return
- 如果不是void,无论在何处返回,那么编译器就会强制返回一个正确类型的返回值
2.6 构建一个Java程序
2.6.1 名字可见性
通过包名可以区分,同一个文件内的每个类都有唯一的标识符
2.6.2 运用其他构件
这个没啥说的,用import来导入一个包,也就是一个类库
2.6.3 static关键字
1、有两种情形用static可以解决:
- 希望没有创建对象,也可以有一个单一内存空间
- 希望没有创建对象,也可以调用某个方法
2、变量或者方法被static修饰时,不会与任何类的对象关联在一起,它是属于整个类的
3、static方法不能调用其他非static域和方法,因为非static必须与某一个对象关联
4、我们可以通过对象来调用方法,也可以直接通过类名来调用此方法
5、static字段对于每个类来说只有一份存储空间,而非static字段则是对每个对象有一个存储空间
6、static方法一个很重要的用法就是在不创建任何对象的前提下就可以直接调用它,而且还能提高访问速度
2.7 你的第一个Java程序
也没啥说的,就这两点吧
- System.out.println(new Date()),System这个类调用静态对象out调用静态方法println
- 打印语句这行代码执行完之后,Date对象不再被使用,会被自动回收的
2.7.1 编译和运行
没啥可说的
2.8 注释和嵌入式文档
这个也简单
单行注释://
多行注释:/* */
2.8.1 注释文档
文档注释:/** */
写文档注释是很重要的,对于维护也是很有用的
2.8.2 语法
语法就是那样的语法,javadoc只能为public和protected成员进行文档注释,不过可以用-private来进行标记
最后导出的结果是一个HTML文件,很方便的看到自己设计的类,这是很值得的
2.8.3 嵌入式HTML
这个没啥说的
2.8.4 一些标签示例
这个也不带的写了,常用的就那么几个,param、return、author等
2.8.5 文档示例
不说了
2.9 编码风格
没啥说的,驼峰风格,其他的很多编程规范参考阿里巴巴Java开发手册吧
2.10 总结
Java语言的基本思想已经有了一个总体的认识,再接再励吧!
2.11 练习
练习1、验证Java执行了默认初始化
public class E01_DefaultInitialization {
int i;
char c;
public E01_DefaultInitialization() {
System.out.println("i = " + i);
System.out.println("c = [" + c + ']');
}
public static void main(String[] args) {
new E01_DefaultInitialization();
}
}
练习2、打印Hello World!
public class E02_HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, world!");
}
}
练习3、创建一个对象
public class E03_ATypeName {
public static void main(String[] args) {
E03_ATypeName a = new E03_ATypeName();
}
}
练习4、创建一个对象并给它们赋值
public class E04_DataOnly {
int i;
double d;
boolean b;
public static void main(String[] args) {
E04_DataOnly d = new E04_DataOnly();
d.i = 47;
d.d = 1.1;
d.b = false;
}
}
练习5、在main方法中赋值并打印出来
public class E05_DataOnly2 {
public static void main(String[] args) {
E04_DataOnly d = new E04_DataOnly();
d.i = 47;
System.out.println("d.i = " + d.i);
d.d = 1.1;
System.out.println("d.d = " + d.d);
d.b = false;
System.out.println("d.b = " + d.b);
}
}
练习6、判断String的长度通过调用方法,在方法中return后输出
public class E06_Storage {
String s = "Hello, World!";
int storage(String s) {
return s.length() * 2;
}
void print() {
System.out.println("storage(s) = " + storage(s));
}
public static void main(String[] args) {
E06_Storage st = new E06_Storage();
st.print();
}
}
练习7、静态方法调用静态变量,也可通过对象调用
class StaticTest {
static int i = 47;
}
public class E07_Incrementable {
static void increment() {
StaticTest.i++;
}
public static void main(String[] args) {
E07_Incrementable sf = new E07_Incrementable();
sf.increment();
E07_Incrementable.increment();
increment();
}
}
练习8、无论创建多少个对象,static域只有一个实例
public class E08_StaticTest {
static int i = 47;
public static void main(String[] args) {
E08_StaticTest st1 = new E08_StaticTest();
E08_StaticTest st2 = new E08_StaticTest();
System.out.println(st1.i + " == " + st2.i);
st1.i++;
System.out.println(st1.i + " == " + st2.i);
}
}
练习9、自动包装功能对所有的基本类型和包装器类型都起作用
public class E09_AutoboxingTest {
public static void main(String[] args) {
Byte by = 1;
byte bt = by;
System.out.println("byte = " + bt);
Short sh = 1;
short s = sh;
System.out.println("short = " + s);
Integer in = 1;
int i = in;
System.out.println("int = " + i);
Long lo = 1L;
long l = lo;
System.out.println("long = " + l);
Boolean bo = true;
boolean b = bo;
System.out.println("boolean = " + b);
Character ch = 'x';
char c = ch;
System.out.println("char = " + c);
Float fl = 1.0f;
float f = fl;
System.out.println("float = " + f);
Double db = 1.0d;
double d = db;
System.out.println("double = " + d);
}
}
练习10、打印从命令行获取的三个参数
public class E10_ShowArgs {
public static void main(String[] args) {
System.out.println(args[0]);
System.out.println(args[1]);
System.out.println(args[2]);
}
}
public class E10_ShowArgs2 {
public static void main(String[] args) {
if(args.length < 3) {
System.err.println("Need 3 arguments");
System.exit(1);
}
System.out.println(args[0]);
System.out.println(args[1]);
System.out.println(args[2]);
}
}
练习11、这个在书中没出现,不过就是通过一个方法来改变成员变量的值
public class E11_AllTheColorsOfTheRainbow {
int anIntegerRepresentingColors;
void changeTheHueOfTheColor(int newHue) {
anIntegerRepresentingColors = newHue;
}
public static void main(String[] args) {
E11_AllTheColorsOfTheRainbow all = new E11_AllTheColorsOfTheRainbow();
all.changeTheHueOfTheColor(27);
}
}
下面的都略了,要打开浏览器查看javadoc文档,那就自己打开验证吧
练习12、
练习13、
练习14、
练习15、
练习16、
上一篇: c语言函数学习
下一篇: PCL点云库:ICP算法原理及应用