stronger distinctions between numeric, enumeration, array, and pointer types, an Ada version of an API can reduce the likelihood of inappropriate use, and identify more such errors at compile-time.
At run-time, Ada has pointer default initialization, pointer null checking, array bounds checking, with user control over both the low and high bound, and conversion checking. In addition, Ada provides range checking, variant record checking, and, in Ada 95, both compile-time and run-time checks designed to eliminate "dangling" references associated with pointers to deallocated stack variables. This set of "dangling reference" checks ("accessibility checks") allows an embedded or critical program to avoid completely the use of dynamic storage allocation, while still providing the convenience of using pointers.
Both Ada and Java have support for multithreaded applications as a standard, portable part of the language, whereas C and C++ support multithreading generally through operating-system-dependent libraries. The Ada multithreading support includes various real-time-oriented features, such as timed entry calls and selective accepts with delay alternatives, whereas Java has only a basic timed "sleep" operation. To the basic Ada 83 multithreading support, Ada 95 adds protected objects, which are designed to support real-time systems by reducing overhead, minimizing "priority inversion," and generally improving predictability of thread synchronization. Java's synchronized methods, with wait/notify operations, provide similar capability, although with less encapsulation of the fields requiring synchronized access, a more race-prone "notification"-oriented synchronization model, and no particular concern for priority inversion.
Although Ada is a general-purpose 3GL, it was designed with extra attention to the concerns of real-time, embedded, and critical systems developers, namely very thorough consistency checking, mechanisms to support a very "static" storage allocation model, and multithreading support with time and priority-cognizant constructs. As such, at a technical level, it is a better fit to the needs of DOD critical and embedded systems development than are the other languages in widespread commercial use. These reliability-oriented features of the Ada language make development and maintenance more cost-effective, when cost to achieve the required level of quality and correct functionality is included. Of course, there are other non-technical issues involved in language choice (as discussed in Chapter 1), and other non-language issues involved in managing successful software development (discussed in Chapter 2).