Appendix E

More Java Keywords

image

There are five Java keywords not discussed elsewhere in this book. They are:

image transient

image volatile

image native

image strictfp

image assert

These keywords are most often used in programs more advanced than those found in this book. However, an overview of each is presented so that you will know their purpose. In addition, another form of this is described.

The transient and volatile Modifiers

The transient and volatile keywords are type modifiers that handle somewhat specialized situations. When an instance variable is declared as transient, then its value need not persist when an object is stored. Thus, a transient field is one that does not affect the persisted state of an object.

The volatile modifier tells the compiler that a variable can be changed unexpectedly by other parts of your program. One of these situations involves multithreaded programs. In a multithreaded program, sometimes two or more threads will share the same variable. For efficiency considerations, each thread can keep its own, private copy of such a shared variable, possibly in a register of the CPU. The real (or master) copy of the variable is updated at various times, such as when a synchronized method is entered. While this approach works fine, there may be times when it is inappropriate. In some cases, all that really matters is that the master copy of a variable always reflects the current state, and that this current state is used by all threads. To ensure this, declare the variable as volatile.

strictfp

One of the more esoteric keywords is strictfp. When Java 2 was released several years ago, the floating-point computation model was relaxed slightly. Specifically, the new model did not require the truncation of certain intermediate values that occur during a computation. This prevented overflow or underflow in some cases. By modifying a class, method, or interface with strictfp, you could ensure that floating-point calculations (and thus all truncations) took place precisely as they did in earlier versions of Java. When a class was modified by strictfp, all of the methods in the class were also strictfp automatically. However, beginning with JDK 17, all floating-point computations are now strict and strictfp is obsolete and no longer required. Its use will now generate a warning message.

REMEMBER

Beginning with JDK 17, the keyword strictfp is obsolete and its use will now generate a warning message.

assert

The assert keyword is used during program development to create an assertion, which is a condition that is expected to be true during the execution of the program. For example, you might have a method that should always return a positive integer value. You might test this by asserting that the return value is greater than zero using an assert statement. At run time, if the condition actually is true, no other action takes place. However, if the condition is false, then an AssertionError is thrown. Assertions are often used during testing to verify that some expected condition is actually met. They are not usually used for released code.

The assert keyword has two forms. The first is shown here:

assert condition;

Here, condition is an expression that must evaluate to a Boolean result. If the result is true, then the assertion is true and no other action takes place. If the condition is false, then the assertion fails and a default AssertionError object is thrown. For example,

assert n > 0;

If n is less than or equal to zero, then an AssertionError is thrown. Otherwise, no action takes place.

The second form of assert is shown here:

assert condition : expr;

In this version, expr is a value that is passed to the AssertionError constructor. This value is converted to its string format and displayed if an assertion fails. Typically, you will specify a string for expr, but any non-void expression is allowed as long as it defines a reasonable string conversion.

To enable assertion checking at run time, you must specify the -ea option. For example, to enable assertions for Sample, execute it using this line:

java -ea Sample

Assertions are quite useful during development because they streamline the type of error checking that is common during testing. But be careful—you must not rely on an assertion to perform any action actually required by the program. The reason is that normally, released code will be run with assertions disabled and the expression in an assertion will not be evaluated.

Native Methods

Although rare, there may occasionally be times when you will want to call a subroutine that is written in a language other than Java. Typically, such a subroutine will exist as executable code for the CPU and environment in which you are working—that is, native code. For example, you may wish to call a native code subroutine in order to achieve faster execution time. Or you may want to use a specialized, third-party library, such as a statistical package. However, since Java programs are compiled to bytecode, which is then interpreted (or compiled on the fly) by the Java run-time system, it would seem impossible to call a native code subroutine from within your Java program. Fortunately, this conclusion is false. Java provides the native keyword, which is used to declare native code methods. Once declared, these methods can be called from inside your Java program just as you call any other Java method.

To declare a native method, precede the method with the native modifier, but do not define any body for the method. For example:

public native int meth() ;

Once you have declared a native method, you must provide the native method and follow a
rather complex series of steps in order to link it with your Java code.

Another Form of this

There is another form of this that enables one constructor to invoke another constructor within the same class. You saw an example of this usage in Chapter 16 where it was required when creating a non-canonical record constructor. Its use is, however, not limited to that situation. It is often used to reduce code duplication. The general form of this use of this is shown here:

this(arg-list)

When this( ) is executed, the overloaded constructor that matches the parameter list specified by arg-list is executed first. Then, if there are any statements inside the original constructor, they are executed. The call to this( ) must be the first statement within the constructor. Here is a simple example:

image

In MyClass, only the first constructor actually assigns a value to a and b. The second constructor simply invokes the first. Therefore, when this statement executes:

MyClass mc = new MyClass(8);

the call to MyClass(8) causes this(8, 8) to be executed, which translates into a call to MyClass(8, 8).

As mentioned, invoking overloaded constructors through this( ) can be useful because it can prevent the unnecessary duplication of code. However, you need to be careful. Constructors that call this( ) may execute a bit slower than those that contain all of their initialization code in-line. This is because the call and return mechanism used when the second constructor is invoked adds overhead. Remember that object creation affects all users of your class. If your class will be used to create large numbers of objects, then you must carefully balance the benefits of smaller code against the increased time it takes to create an object. As you gain more experience with Java, you will find these types of decisions easier to make.

There are two restrictions you need to keep in mind when using this( ). First, you cannot use any instance variable of the constructor’s class in a call to this( ). Second, you cannot use super( ) and this( ) in the same constructor because each must be the first statement in the constructor.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.106.225