Java和C++在细节上的差异(一) (二)

2014-11-24 03:03:11 · 作者: · 浏览: 2
ava的对象变量看做C++中的对象指针,如:BirthdayDate d; /*Java*/ 等同于 BirthdayDate* d; /*C++*/。
  与Java对象实例声明的方式相同,C++中的对象指针也是通过new的方式进行初始化的,如BirthdayDate* d = new BirthdayDate. 同样可以将C++中的对象指针赋值为NULL,也可以将其重新赋值指向另外一个对象实例。与Java相同,通过new操作符创建的对象实例是存储在堆中的,不同的是,Java的对象在创建后,无需开发人员在去关注该对象实例需要合适被释放,所有的操作均有Java虚拟机中提供的垃圾回收机制自动完成。而C++中的该类对象,则需要开发人员通过调用delete操作符来自行完成释放,如果忘记释放将会产生内存泄露。在C++中,不仅可以将对象存储在堆上,同样也可以定义并存储的栈上,如BrithdayDate d; 该对象实例不需要手工释放,在栈退出时将自动释放该对象的存储空间,同时也会调用该对象的析构函数。
  2. Java对象方法的显式参数和隐式参数:
1 public class Employee {
2 public void raiseSalary(double byPercent) {
3 double raise = salary + byPercent / 100;
4 salary += raise;
5 }
6 private double salary;
7 }
  raiseSalary是Employee类的一个成员方法,该方法是由两个参数构成,一个是显式参数byPercent,另一个则是隐式参数this,既raiseSalary方法是实现体可以改为:
1 public void raiseSalary(double byPercent) {
2 double raise = this.salary + byPercent / 100;
3 this.salary += raise;
4 }
  这里的隐式参数this表示当前调用raiseSalary方法的对象实例的自身,该机制和C++基本相同。
  注:静态方法中不存在该特征。
  3. Java对象中定义的final实例域,如:public class Employee { ... private final String name; }, 该类型的field必须在对象构造函数中进行初始化,之后该变量将不能再被重新赋值。和final字段相似,C++对象中的const成员变量也必须在对象构造函数的初始化列表中完成赋值任务,在之后的使用中该字段将不会再被修改,否则会产生编译错误。对于Java的final域而言,以便应用于基本数据类型,如int,double等,或者不可变类型,如String。对于可变类型而言,final修饰符可能会造成某些预料之外的混乱,如 private final Date hiredate; 当该field作为某个get方法的返回值返回给调用者之后,final的修饰作用只能保证返回后的date对象不能再被重新赋值并指向新的对象实例引用,但是可以通过直接修改返回值对象的自身数据来破坏对象的封装性,从而可能造成数据的非法性,或者状态的不一致性。
  4. 函数参数传递的方式:传值和传引用。
  在Java中调用函数是,参数都是通过传值的方式传递到函数内部,然而根据参数类型的不同,其表现仍然存在一定的差异。主要总结为以下3点:
  被调用方法不能修改一个基本数据类型的参数,如:int,double,boolean等,见如下代码:
1 private static void tripleva lue(double x) {
2 x *= 3;
3 System.out.println("End of method: x = " + x);
4 }
5
6 public static void testTripleva lue() {
7 System.out.println("Test tripleva lue");
8 double percent = 10;
9 System.out.println("Before: percent = " + percent);
10 tripleva lue(percent);
11 System.out.println("After: percent = " + percent);
12 }
13 /* 结果如下:
14 Test tripleva lue
15 Before: percent = 10.0
16 End of method: x = 30.0
17 After: percent = 10.0 */
  被调用方法可以改变一个对象参数的状态,见如下代码:
1 private static void tripleSalary(Employee x) {
2 x.raiseSalary(200);
3 System.out.println("End of method: salary = " + x.getSalary());
4 }
5
6 public static void testTripleSalary() {
7 System.out.println("Test tripleSalary");
8 Employee harry = new Employee("Harry",50000);
9 System.out.println("Before: salary = " + harry.getSalary());
10 tripleSalary(harry);
11 System.out.println("After: salary = " + harry.getSalary());
12 }
13 /* 结果如下:
14 Test tripleSalary
15 Before: salary = 50000.0
16 End of method: x = 150000.0
17 After: salary = 150000.0 */
  被调用方法不能实现让对象参数引用一个新的对象,见如下代码:
1 private static void swap(Employee a,Employee b) {
2 Employee temp = x;
3 x = y;
4 y = temp;
5 System.out.println("End of method: x = " + x.getName());
6 System.out.println("End of method: y = " + y.getName());
7 }
8 public static void testSwap() {
9 System.out.println("Test Swap");
10 Emp