1.5. Nonaccess modifiers

[7.5] Use abstract classes and interfaces

[6.2] Apply the static keyword to methods and fields

This section discusses the nonaccess modifiers abstract, final, and static. Access modifiers control the accessibility of your class and its members outside the class and the package. Nonaccess modifiers change the default behavior of a Java class and its members.

For example, if you add the keyword abstract to the definition of a class, it can’t be instantiated. Such is the magic of the nonaccess modifiers.

You can characterize your classes, interfaces, methods, and variables with the following nonaccess modifiers (though not all are applicable to each Java entity):

  • abstract
  • static
  • final
  • synchronized
  • native
  • strictfp
  • transient
  • volatile

The OCA Java SE 8 Programmer I exam covers only three of these nonaccess modifiers: abstract, final, and static, which I’ll cover in detail. To ward off any confusion about the rest of the modifiers, I’ll describe them briefly here:

  • synchronized—A synchronized method can’t be accessed by multiple threads concurrently. You can’t mark classes, interfaces, or variables with this modifier.
  • native—A native method calls and makes use of libraries and methods implemented in other programming languages such as C or C++. You can’t mark classes, interfaces, or variables with this modifier.
  • transient—A transient variable isn’t serialized when the corresponding object is serialized. The transient modifier can’t be applied to classes, interfaces, or methods.
  • volatile—A volatile variable’s value can be safely modified by different threads. Classes, interfaces, and methods can’t use this modifier.
  • strictfp—Classes, interfaces, and methods defined using this keyword ensure that calculations using floating-point numbers are identical on all platforms. This modifier can’t be used with variables.

Now let’s look at the three nonaccess modifiers that are on the exam.

1.5.1. abstract modifier

When added to the definition of a class, interface, or method, the abstract modifier changes its default behavior. Because it is a nonaccess modifier, abstract doesn’t change the accessibility of a class, interface, or method.

Let’s examine the behavior of each of these with the abstract modifier.

abstract class

When the abstract keyword is prefixed to the definition of a concrete class, it changes it to an abstract class, even if the class doesn’t define any abstract methods. The following code is a valid example of an abstract class:

abstract class Person {
    private String name;
    public void displayName() { }
}

An abstract class can’t be instantiated, which means that the following code will fail to compile:

Here’s the compilation error thrown by the previous class:

University.java:4: Person is abstract; cannot be instantiated
    Person p = new Person();
               ^
1 error
Exam Tip

An abstract class may or may not define an abstract method. But a concrete class can’t define an abstract method.

abstract interface

An interface is an abstract entity by default. The Java compiler automatically adds the keyword abstract to the definition of an interface. Thus, adding the keyword abstract to the definition of an interface is redundant. The following definitions of interfaces are the same:

abstract method

An abstract method doesn’t have a body. Usually, an abstract method is implemented by a derived class. Here’s an example:

Exam Tip

A method with an empty body isn’t an abstract method.

abstract variables

None of the different types of variables (instance, static, local, and method parameters) can be defined as abstract.

Exam Tip

Don’t be tricked by code that tries to apply the nonaccess modifier abstract to a variable. Such code won’t compile.

1.5.2. final modifier

The keyword final can be used with the declaration of a class, variable, or method. It can’t be used with the declaration of an interface.

final class

A class that’s marked final can’t be extended by another class. The class Professor won’t compile if the class Person is marked as final, as follows:

final interface

An interface can’t be marked as final. An interface is abstract by default and marking it with final will prevent your interface from compiling:

final variable

A final variable can’t be reassigned a value. It can be assigned a value only once. See the following code:

Compare the previous example with the following code, which tries to reassign a value to a final variable:

It’s easy to confuse reassigning a value to a final variable with calling a method on a final variable, which might change the state of the object that it refers to. If a reference variable is defined as a final variable, you can’t reassign another object to it, but you can call methods on this variable (that modify its state):

final method

A final method defined in a base class can’t be overridden by a derived class. Examine the following code:

If a method in a derived class has the same method signature as its base class’s method, it’s referred to as an overridden method. Overridden methods are discussed along with polymorphism in chapter 6.

1.5.3. static modifier

The nonaccess modifier static can be applied to the declarations of variables, methods, classes, and interfaces. We’ll examine each of them in following sections.

static variables

static variables belong to a class. They’re common to all instances of a class and aren’t unique to any instance of a class. static attributes exist independently of any instances of a class and may be accessed even when no instances of the class have been created. You can compare a static variable with a shared variable. A static variable is shared by all the objects of a class.

Note

A class and an interface can declare static variables. This section covers declaration and usage of static variables that are defined in a class. Chapter 6 covers interfaces and their static variables in detail.

Think of a static variable as being like a common bank vault that’s shared by the employees of an organization. Each of the employees accesses the same bank vault, so any change made by one employee is visible to all the other employees, as illustrated in figure 1.33.

Figure 1.33. Comparing a shared bank vault with a static variable

Figure 1.34 defines a class Emp that defines a non-static variable name and a static variable bankVault.

Figure 1.34. Definition of the class Emp with a static variable bankVault and non-static variable name

It’s time to test what we’ve been discussing up to this point. The following TestEmp class creates two objects of the class Emp (from figure 1.34) and modifies the value of the variable bankVault using these separate objects:

In the preceding code example, emp1.bankVault, emp2.bankVault, and Emp.bank-Vault all refer to the same static attribute: bankVault.

Exam Tip

Even though you can use an object reference variable to access static members, it’s not advisable to do so. Because static members belong to a class and not to individual objects, using object reference variables to access static members may make them appear to belong to an object. The preferred way to access them is by using the class name. The static and final nonaccess modifiers can be used together to define constants (variables whose value can’t change).

In the following code, the class Emp defines the constants MIN_AGE and MAX_AGE:

Although you can define a constant as a non-static member, it’s common practice to define constants as static members, because doing so allows the constant values to be used across objects and classes.

static methods

static methods aren’t associated with objects and can’t use any of the instance variables of a class. You can define static methods to access or manipulate static variables:

It’s a common practice to use static methods to define utility methods, which are methods that usually manipulate the method parameters to compute and return an appropriate value:

static double interest(double num1, double num2, double num3) {
    return(num1+num2+num3)/3;
}

The following utility (static) method doesn’t define input parameters. The method averageOfFirst100Integers computes and returns the average of numbers 1 to 100:

The nonprivate static variables and methods are inherited by derived classes. The static members aren’t involved in runtime polymorphism. You can’t override the static members in a derived class, but you can redefine them.

Any discussion of static methods and their behavior can be quite confusing if you aren’t aware of inheritance and derived classes. But don’t worry if you don’t understand all of it. I’ll cover derived classes and inheritance in chapter 6. For now, note that a static method can be accessed using the name of the object reference variables and the class in a manner similar to static variables.

What can a static method access?

Neither static methods nor static variables can access the non-static variables and methods of a class. But the reverse is true: non-static variables and methods can access static variables and methods because the static members of a class exist even if no instances of the class exist. static members are forbidden from accessing instance methods and variables, which can exist only if an instance of the class is created.

Examine the following code:

This is the compilation error thrown by the previous class:

MyClass.java:3: nonstatic method count() cannot be referenced from a static context
    static int x = count();
                   ^
1 error

The following code is valid:

Exam Tip

static methods and variables can’t access the instance members of a class.

Table 1.4 summarizes the access capabilities of static and non-static members.

Table 1.4. Access capabilities of static and non-static members

Member type

Can access static attribute or method?

Can access non-static attribute or method?

static Yes No
Non-static Yes Yes
Accessing static members from a null reference

Because static variables and methods belong to a class and not to an instance, you can access them using variables, which are initialized to null. Watch out for such questions in the exam. Such code won’t throw a runtime exception (NullPointer-Exception to be precise). In the following example, the reference variable emp is initialized to null:

Exam Tip

You can access static variables and methods using a null reference.

static classes and interfaces

Certification aspirants frequently ask questions about static classes and interfaces, so I’ll quickly cover these in this section to ward off any confusion related to them. But note that static classes and interfaces are types of nested classes and interfaces that aren’t covered by the OCA Java 8 Programmer I exam.

You can’t prefix the definition of a top-level class or an interface with the keyword static. A top-level class or interface is one that isn’t defined within another class or interface. The following code will fail to compile:

static class Person {}
static interface MyInterface {}

But you can define a class and an interface as a static member of another class. The following code is valid:

The next section covers features of Java that led to its popularity two decades ago, and which still hold strong.

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

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