比較C++和Java 二

26.Java内置多线程支持。你能够通过继承Thread类来创建一个新的线程(重写run()方法)。相互排斥发生在使用synchronized关键字作为类型修饰符修饰方法的对象级别。

在任一时刻,仅仅能有一个线程訪问特定对象的synchronized方法。换句话说,当进入一个synchronized方法时。首先会去对对象“上锁”。这对使用该对象的其它synchronized方法也有作用,而且当退出方法时“解锁”对象。

没有显式的锁;上锁和解锁都是自己主动的。你依然须要自己通过创建你自己的“监控者”类实现更加复杂的线程同步。递归的同步方法工作正常。时间片分配在相同优先级的线程之间得不到保证。

27.不同于C++使用控制块的声明。訪问修饰符(publicprivate,和protected)被置于类中每一个成员的定义处。没有显式的訪问修饰符,一个元素默觉得”friendly”,能够被同一个包下的其它元素訪问(他们相当于都是C++中的友元),可是不能被包外的元素訪问。

类。和类中的每一个方法,都有訪问限定符去决定其是否对文件外可见。

有时private关键字在Java中非常少使用,由于“友好”訪问权限比把同一个包下的其它类的訪问排除在外通常更有用。(然而,对于多线程,private的正确使用是非常必要的。

)Java中protected关键字意为“对于继承者和同一个包下的类可訪问。”这与C++中的protected不同,C++中含义为“仅仅同意继承者訪问”(private protected用来实现一样的效果,可是这对关键字的使用被取消了)。

28.嵌套类。

在C++中,嵌套一个类目的在于名称隐藏和代码组织(可是C++的名称空间消除了名称隐藏的需求)。Java包机制提供了相似于名称空间的效果,所以名称隐藏对于Java而言不算是个问题。Java 1.1的内部类看起来如同内嵌类一样。

然而。一个内部类的对象私藏着參与了内部类对象创建的外部类对象的引用。这意味着内部类对象能够无限制的訪问外部类对象的成员,好像那些成员直接属于内部类一般。这提供了对于回调问题更加简洁的解决方式。在C++中使用指针来解决该问题。

29.由于上一点所介绍的内部类,Java中没有指向成员的指针。

30.没有内联方法。Java编译器能够自己决定内联一个方法,可是你对此没有太多控制力。你能够使用final关键字建议内联一个方法。然而,inline函数也仅仅是对C++编译器的建议。

31.Java的继承与C++有一样的作用,可是详细的语法有所不同。Java使用extends关键字来从基类进行继承,使用super关键字去调用基类中与子类同名的方法(然而,Java中super关键字仅仅同意去訪问直接父类中的方法,仅仅能向上追溯一级。

C++中则同意訪问更深层的基类方法。

)基类的构造器相同使用super关键字调用。

正如之前提到的,全部的类终于均继承自Object类。Java中不像C++。没有显式的构造初始化列表。可是Java编译器强制你去在构造器方法中首先初始化基类。编译器不同意你之后再对基类进行初始化。Java中通过结合自己主动初始化与未初始化对象引用异常来保证成员的初始化。

public class Foo extends Bar {
  public Foo(String msg) {
    super(msg); // Calls base constructor
    public baz(int i) { // Override
      super.baz(i); // Calls base method
    }
  }
}

32.Java中的继承并不改变基类中成员的保护级别。

Java中和C++不同。你无法指定publicprivate,或者protected继承。

相同,重写基类的方法也无法降低基类方法的訪问权限。

比如,假设基类中的方法是public的,假设你重写了该方法。那么你所重写的方法訪问权限也必须是public的(编译器会对此进行检查)。

33.Java提供interface关键字,来创建一个仅仅包含抽象方法而且没有数据成员的相似于抽象基类的类。这一机制将仅被设计用来作为接口与通过extends关键字拓展现有功能两者做出了清晰的划分。值得一提的是,abstract关键字会产生相似的效果,不能创建该类的对象。

一个abstract类能够包含抽象方法(尽管不要求必须包含)。可是它也能够包含实现,这使其受限于单继承。使用接口这一机制,防止了对于像C++中虚拟基类的需求。
使用implements关键字来创建可被实例化的interface版本号。其语法看起来和继承相像:

public interface Face {
  public void smile();
}

public class Baz extends Bar implements Face {
  public void smile() {
    System.out.println("a warm smile.");
  }
}

34.Java中没有virtual关键字,由于Java中的全部非静态方法均使用动态绑定。因此,Java程序猿无需决定是否採用动态绑定。C++中存在virtual关键字是由于这样你就能够在进行性能调校时不使用它以获得轻微的性能提升(或者。换句话说,“假设你不用它。你就能够免受其累”)。这一般会造成混淆与意外。final关键字为性能优化提供了一些余地 – 它让编译器知道所修饰的方法不能被重写。也就因此其可能被静态绑定(将其内联。因此用起来相当于C++的非虚方法调用)。这些优化取决于编译器。

35.Java不支持多继承(MI)。至少和C++不在相同的意义上(支持)。如同protected,MI似乎挺好的,可是你知道仅仅有当你面对某个设计问题时,你才须要它。由于Java使用单根继承,你将非常少遇到须要MI的情况。interface关键字负责(让你能够)结合(使用)多接口。

36.执行时类型检查功能同C++中的非常相像。为了获知引用X的信息,你能够这样做。比如:

X.getClass().getName();

进行类型安全的下转型,你能够这样:

derived d = (derived)base;

和C中强制类型转换的样子一样。编译器无需额外的语法。会自己主动调用动态转换机制。尽管这没有C++中“new casts”的自解释优点,可是Java会检查其使用情况并适时抛出异常。不会同C++中一般有错误的转换。

37.Java中由于没有析构函数,其异常处理与C++有所不同。能够加入finally子句块去强制执行必须的清理语句。

Java中全部的异常类型都是Throwable类的子类,这样的情况保证你能够有一个通用接口。

public void f(Obj b) throws IOException {
  myresource mr = b.createResource();
  try {
    mr.UseResource();
  } catch (MyException e) {
    // handle my exception
  } catch (Throwable e) {
    // handle all other exception
  } finally {
    mr.dispose(); // special cleanup
  }
}

38.Java的异常规范同C++相比有非常大优势。不像C++的方式,在执行时调用函数。当发生错误异常被抛出,Java异常规范在编译时被核查并执行。除此之外。重写后的方法必须遵循异常规范:同基类中被重写的方法相比,重写的方法能够抛出与被重写方法相同类型或是其子类型的异常。

这提供了更为健壮的异常处理代码。

39.Java有方法重载。可是没有操作符重载。

String类使用++=操作符来连接字符串,而且String表达式使用自己主动的类型转换,但这仅仅是特殊的内置情况。

40.C++中的const问题在Java中非常自然的就避免了。你仅仅能向对象传递引用,而且不会为你自己主动生成本地副本。

假设你想要同C++一样的传值,你能够调用clone()去生成參数的本地副本(尽管clone()机制设计的有些不好 – 见第12章)。


Java中不会自己主动调用拷贝构造函数。


创建一个编译时常量,你能够这样:

static final int SIZE = 255;
static final int BSIZE = 8 * 255;

41.由于安全问题,编写一个“程序”同编写一个“applet”是有非常大差别的。

一个重要的问题是applet将不会让你写磁盘。由于这将同意一个程序从一台未知机器上进行下载而弄脏你的磁盘。这样的情况随着Java 1.1数字签名的应用而有些改观。(数字签名)让你明白地知道每一个程序的作者对你的系统所拥有的特殊权限(当中的一个可能弄脏了你的磁盘;你须要知道是哪一个和发生了什么。)。Java 1.2也承诺了对applets的更强大支持。

42.由于Java在某些情况下具有非常强的限制性,你可能被阻止进行重要的任务。比如直接訪问硬盘。Java通过native method来解决这一问题,使用本地方法,你能够调用还有一种语言编写的程序(眼下仅支持C和C++)。这样一来。你就能够处理针对平台的问题(以一种相对而言不可移植的方式,然而。代码是单独的)。Applets无法调用本地方法。仅仅有应用程序能够。

43.Java对于凝视文档提供了内置支持,所以,源码文件能够包含其自己的文档,这些文档之后会被一个程序剥离并又一次格式化为HTML形式。这对于文档维护和使用而言是一个好消息。

44.Java包含解决特定任务的标准库。C++则依赖第三方非标准库。这些任务包含(或者将非常快包含):
- 网络
- 数据库连接(通过JDBC)
- 多线程
- 分布式对象(通过RMI和CORBA)
- Commerce
这些库有用性和标准性的本质使得能够更快的完毕程序开发。

45.Java 1.1包含Java Beans标准,这可用于在可视化编程环境下创建组件。

这推动了可用于全部开发商开发环境下的可视化组件(的发展)。

由于你不同特定开发商设计的可视化组件相关联,这使得组件的选择性和有用性更好。

除此之外。Java Beans的设计对于程序猿而言更好理解;特定开发商的组件框架往往具有陡峭的学习曲线。

46.假设对Java引用的訪问失败,就会抛出异常。

这在引用被使用前不会发生;Java规范仅仅指明异常必须以某种方式被抛出。

很多C++执行时系统相同能够为坏指针抛出异常。

47.整体而言。Java更加健壮,凭借:
- 对象引用被初始化为null(一个关键字)
- 引用会被检查而且当失败时会抛出异常
- 全部的数组訪问都会进行越界检查
- 自己主动的垃圾收集机制防止内存泄露
- 简洁。相对可靠的异常处理
- 对于多线程的简单语言支持
- 网络applets的字节码校验

posted @ 2018-01-22 19:25  llguanli  阅读(131)  评论(0编辑  收藏  举报