这些JAVA学习笔记的重点将在比较C++和JAVA的一些不同,但不会区分谁优谁劣。这些笔记是在我看Thinking in JAVA这本书时写的,我虽然很熟悉C/C++但是对于JAVA有一些概念但仍然是一个新手。
这个部分的笔记针对的是Thinking in JAVA 3rd p65-p140的一些东西。
一、变量
C/C++当中我认为变量可以分为三大类:基本的变量、指针和引用,基本变量是分配在堆栈上的一块内存,他既可以是基本类型(int或者double之类)也可以是类类型,他的生存周期是受到生存域所控制的;而指针则是一个存储另一块内存(内存的内容可以是基本变量也可以是类类型)地址的变量,本质上讲你可以认为他是一个32位无符号的整型(针对32bit的机器),因此他也像unsinged long一样占有一块内存,只不过是内存当中存放的内容是另一块内存的地址而已,当然数组从本质上讲也认为是指针;而引用这个C++当中新出现的东西则可以认为是对指针的一种封装。
JAVA当中则没有这么复杂,JAVA只需要记住,诸如int double boolean(JAVA叫boolean不是bool)这些东西的变量还是基本变量,他的储存位置还是堆栈生命周期还是受到生存域的控制,而对于类类型,他只有一种变量类型,那就是引用,也就是说假设你写了一个class A,那么不管在什么情况下,即便是函数参数或者返回值他都是引用,类类型对象之间的赋值也只不过是引用指向的转换而不是内存的复制。
比如说:
class A{
int val;
}
A a; //这是一个空引用,你不能写诸如a.val之类的东西
A a = new A(); //要定义一个对象必须要这么做,类类型对象只能通过new在堆上创建
A a1 = new A();
a.val = 2;
a1.val = 3;
a = a1; //这样做直接导致了a和a1同时指向同一块内存,意味着改变a.val同时会改变a1.val
二、作用域
这个部分相对简单,C/C++当中经常看见的一种用法是内部作用域覆盖外部作用域,而JAVA则不允许,他会直接报错。比如:
{
int x = 12;
{
int x = 13;
}
}
C/C++当中这种写法是允许的,并且内部花括号当中的x在定义后覆盖了外部的x,也就是说在内部,外面的x看不见了,修改或者读取x的值都是内部的,当出了内部花括号,内部的x被销毁,外部的x重新可见。但是在JAVA当中这种用法被当作错误。
三、import和include、using
C/C++当中使用include来引入一个头文件,引入一些类和常量的声明。JAVA当中没有头文件和定义文件这样的区分,JAVA的类写法不存在声明一说,当然也不会存在前向声明和先声明后使用的说法。同样,JAVA和C++都会采取一些措施来防止名字冲突,C++用了命名空间,JAVA用了包这个概念,两者可以认为等同,但是有区别,C++的命名空间可以跨文件合并,JAVA每个文件都被认为是一个包,包名即为文件名。因此,引用其他包的类JAVA用import来导入,C++用include来导入头文件用using来导入名字空间,两者效果一样。
四、类的书写格式
C/C++使用头文件和定义文件来书写一个类,头文件只包含声明,也即只有interface,定义文件当中包含了方法的具体代码。并且在头文件当中使用public/protected/private标签来表示这以下到上一个标签以上的方法的访问权限。
JAVA则只有一个文件,他没有声明,因为不需要前向声明所以也没有需要声明的必要性。同时,JAVA采用的是访问权限直接写在每个方法或者成员前面的方式。
我个人更加喜欢C/C++的方式,这种方式相对来讲看起来比较干净整洁,C#也是向JAVA学的类书写方式,看起来很乱,找个方法的调用方式要找半天。
五、限制
可以看到JAVA对一些相对危险的东西做了比C++更加严格的限制。比如说窄化转换,在C++里如果不是显示转换编译器撑死了给你一个warning,但是在JAVA里面直接就丢error给你了,这样就带来了一些对我们这些常年玩CPP的看似负面的影响,比如说我们很习惯把一个数值型放到需要boolean型的语句当中(例如if等等)一直以来认为只要非零就应当代表true,但是JAVA不行,甚至你用显式转换成boolean都不行,必须写成x != 0才行!对普通的一些表达式而言这个规则的影响也不过是如果计算当中存在类型提升那么在赋值回去的时候你得显示转换,所以写表达式的时候多留个心眼就能避免被丢error了。
这一部分大概就是这样了,没什么新的东西,都是一些习惯上需要改变的东西。