Monday, January 3, 2011

Chapter 5: Non-Access Modifiers

In the previous chapter we saw the access modifiers public, private and protected. These are modifiers that specify/set the access levels of java elements. In this chapter we are going to take a look at other modifiers that can alter the behavior of Java elements. They are:

1. Non-Access Class Modifiers
2. Non-Access Member Modifiers

Non-Access Class Modifiers:

In our previous chapters we have taken a look at normal classes that do not have any specific keyword (apart from public) before their names. There are other keywords “final” and “abstract” that can alter the way a class behaves.

There is another modifier strictfp which is something we don't need to dig deep into. For the exam perspective all we need to know is that strictfp is a keyword and can be used to modify the behavior of a class or a method but never on a variable. Making a class strictfp means that any method inside this class will confirm to the IEEE 754 standard rules for floating point calculations. If you don't use this modifier then floating points might behave in a platform dependent way. If you don't want all your methods in a class to be compliant with the IEEE 754 standard, you can specifically make certain methods behave that way by adding the strictfp keyword before the method name.

I repeat – this is all you need to know about strictfp keyword for the SCJP exam and consider yourself lukcy or unlucky whichever way you want to put it if you happen to get a question on this.

Final Classes

When used in a class declaration, the final keyword means the a class can’t be subclassed. In other words, no other class can extend (inherit) a final class, and any attempts to do so will give you a compiler error.

By now you are thinking why would I want to make my class final? Doesn't that defeat the whole Object Oriented concept of Inheritance? (Don't scold me just yet. OO concepts will be a separate subsequent chapter in the SCJP series) The answer is, you should make a class final only if you want to ensure that none of the methods in your class will ever be overridden.
This is exactly the reason why basic java libraries like String class is declared final. People who wrote java wanted to ensure that nobody messes around with the way Strings behave in a program. Imagine the confusion that would ensue if novice programmers have the ability to edit the way a String behaves?

Exercise: If you have a bit of free time in your hand you can try creating your own class that extends from java.lang.String and enjoy the error messages the compiler will throw at you for doing that

In practice, you’ll almost never make a final class. A final class obliterates a key benefit of OO—extensibility. So unless you have a serious safety or security issue, assume that some day another programmer will need to extend your class.

Abstract Classes

An abstract class can never be instantiated. Its sole purpose or rather mission in life is to be extended (subclassed). As you can see an Abstract Class is the exact opposite of final class.
To refresh – You can visit Chapter 2 to read more about what an abstract class is and how to declare an abstract class.

By now you are probably thinking, why would I create a class that I cannot instantiate? The answer is simple, you may want to have a skeleton or template class that you want all your junior programmers to follow and to ensure that they don't write code that suits their whims and fancies you will give them an abstract class that they must extend and provide implementations to all your abstract behavior. At the same time, you can have a few concrete methods that ensure that the class behaves a certain way you want (at the high level).

Tip: You can never have a class that is both Abstract and Final.

Now that we have looked at NonAccess Class Modifiers let us now take a look at

Nonaccess Member Modifiers

Just like Classes, Methods too can have many modifiers that alter the way they work or behave. The modifiers we are going to look in this section are:

1. final
2. abstract
3. transient
4. synchronized
5. native
6. strictfp and
7. static

Final Methods

The final keyword prevents a method from being overridden in a subclass. Final methods are usually placed in classes where you don't want anyone who is extending your code to meddle with a certain piece of functionality. For ex: the Thread class has a method called isAlive() that checks whether a thread is still active. If you extend the Thread class, there is no way that you can correctly implement this method yourself, so the men who coded Java have made it final. Just like you can’t subclass the String class (remember the Exercise in the final classes section), you can’t override many of the methods in the core class libraries. This can’t-be-overridden restriction provides for safety and security, but you should use it with great caution. Preventing a subclass from overriding a method greatly affects many of the benefits of OO including extensibility through polymorphism.

A typical final method declaration looks like this:

public class FinalMethodExampleClass{
public final void youCannotOverrideMe() {
System.out.println("One.");
}
}

It’s legal to extend FinalMethodExampleClass, since the class isn’t marked final, but we can’t override the final method youCannotOverrideMe (), as the following code attempts to do:

class SubClass extends FinalMethodExampleClass {
public void youCannotOverrideMe () {
System.out.println("Two.");
}
}

Attempting to compile the preceding code gives us something like this:

The method void youCannotOverrideMe() declared in class
SubClass cannot override the final method of the same signature
declared in class SuperClass.
Final methods cannot be overridden.
public void youCannotOverrideMe() { }
1 error


Abstract Methods

An abstract method is a method that’s been declared as abstract but not implemented. In other words, the method contains no code. You mark a method abstract when you want to force subclasses to provide the implementation. (remember the reason why you would want to make a class abstract from the previous paragraph)

Ex: public abstract void showSample();

Notice that the abstract method ends with a semicolon instead of curly braces. It is illegal to have even a single abstract method in a class that is not explicitly declared abstract! Look at the following illegal class:

public class IllegalAbstractClass{
public abstract void test();
}

The preceding class will produce the following error if you try to compile it:

IllegalClass.java:1: class IllegalAbstractClass must be declared
abstract.
It does not define void test() from class IllegalAbstractClass.
public class IllegalAbstractClass {
1 error

You can, however, have an abstract class with no abstract methods. The following example will compile fine:

public abstract class LegalAbstractClass{
void test() {
// you can write lots of code here
}
}

In the preceding example, test() is not abstract. Three different clues tell you it’s not an abstract method:
• The method is not marked abstract.
• The method declaration includes curly braces, as opposed to ending in a semicolon. In other words, the method has a method body.
• The method contains actual implementation code.

Any class that extends an abstract class must implement all abstract methods of the superclass, unless the subclass is also abstract. The rule is this:

The first concrete subclass of an abstract class must implement all abstract methods of the superclass.

Concrete just means nonabstract, so if you have an abstract class extending another abstract class, the abstract subclass doesn’t need to provide implementations for the inherited abstract methods. Sooner or later, though, somebody’s going to make a nonabstract subclass (in other words, a class that can be instantiated), and that subclass will have to implement all the abstract methods from up the inheritance tree.

Exam Watch:
Look for concrete classes that don’t provide method implementations for abstract methods of the superclass. The following code won’t compile:
public abstract class A {
abstract void test();
}
class B extends A {
void test(int I) { }
}

Class B will not compile because it doesn’t implement the inherited abstract method test(). Although the test(int I) method in class B might appear to be an implementation of the superclass’ abstract method, it is simply an overloaded method (a method using the same identifier, but different arguments), so it doesn’t fulfill the requirements for implementing the superclass’ abstract method. So you either provide an implementation to the method test() in class B or mark the class Abstract.

Tip: Remember the earlier tip from Non Access Class Modifiers? You cannot have a class that is both final and abstract? The same applies here too. A method cannot be both final and abstract.
It is also important to note that the abstract and static modifiers cannot be used on the same method. We will look at static methods later in the chapter, but for now just remember that the below code wont work.
abstract static void test();

And it would give you an error:
illegal combination of modifiers: abstract and
static
abstract static void test();

Synchronized Methods

The synchronized keyword indicates that a method can be accessed by only one thread at a time. We’ll discuss this topic in great detail (probably until either of us gets bored), but for now all we need to know is that the synchronized modifier can be applied only to methods—not variables, not classes, just methods.

A typical synchronized declaration looks like this:

public synchronized String retrieveUserName(int userId) { }

You should also know that the synchronized modifier can be matched with any of the four access control levels (which effectively means it can be paired with any of the three access modifier keywords).

Native Methods

The native modifier indicates that a method is implemented in platform-dependent code (Not Java Of Course), but often in C. There wont be any questions about how to use native methods for the exam. For now it is enough if you know that native is a modifier (thus a reserved keyword) and that native can be applied only to methods—not classes, not variables, just methods. Note that a native method’s body must be a semicolon (;) (like abstract methods), indicating that the implementation is omitted.

Strictfp Methods

We looked earlier at using strictfp as a class modifier, but even if you don’t declare a class as strictfp, you can still declare an individual method as strictfp. Remember, strictfp forces floating points (and any floating-point operations) to adhere to the IEEE 754 standard. With strictfp, you can predict how your floating points will behave regardless of the underlying platform the JVM is running on. The downside is that if the underlying platform is capable of supporting greater precision, a strictfp method won’t be able to take advantage of it.

Static Methods

Static keyword when used with a method, specifies that this method belongs to the class and not a particular instance of the class (a.k.a object of the class)

Ex:

public class StaticTest {
public static String getAuthorName() {
return “Anand”;
}
}

Here getAuthorName is the static method and it can be accessed without instantiating an object of the class StaticTest. You can access this method as:

String authorName = StaticTest.getAuthorName();

Tip: Though we will be covering static methods in greater depth in subsequent chapters, it is important to know that, a static method cannot and I mean CANNOT access instance variables or methods of the class. It can only access other static methods and variables.

For Ex:

public class StaticTestBad {
private String name = “Rocky”;

public static String getAuthorName () {
return name; //Cant work!!!
}

public int getAge(){
return 28;
}

public static int getAuthorAge() {
return getAge(); //Cant Work Again!!!
}
}

If you try to compile this class, you will get compilation errors at the two lines that I have commented out.

Non Access Member modifiers include modifiers that are applicable to variables in a class as well. The modifiers you can use with variables are:
1. final
2. transient
3. volatile
4. static

Final Variables

Declaring a variable with the final keyword makes it impossible to reassign a different value to that variable once it has been initialized with an explicit value (notice we said explicit rather than default). For primitives, this means that once the variable is assigned a value, the value can’t be altered. For example, if you assign 10 to the int variable x, then x is going to stay 10, forever. That’s pretty straightforward for primitives, but what does it mean to have a final object reference variable? A reference variable marked final can’t ever be reassigned to refer to a different object. The data within the object can be modified, but the reference variable cannot be changed. In other words, if you have a final employee object variable, you can modify aspects of the employee but you cannot have the variable refer to say a manager.

Transient Variables

If you mark an instance variable as transient, you’re telling the JVM to skip (ignore) this variable when you attempt to serialize the object containing it. Don't worry about Serialization just yet. That is a cool feature of java that we shall be seeing in greater detail in one of the subsequent chapters. For not it is enough to know that a transient variable will be ignored when the object is serialized.

Volatile Variables

The volatile modifier tells the JVM that a thread accessing the variable must always reconcile its own private copy of the variable with the master copy in memory. Did you understand that? Don’t worry about it. For the exam, all you need to know about volatile is that, similar to the transient keyword, it can be applied only to instance variables. It is also important to note that using volatile keyword for variable in a class where you are implementing multi-threading is a bad bad idea.

Static Variables

The static modifier tells the system that this particular variable belongs to the class and does not belong to any specific instance of the same. The class will contain only one instance of the static variable irrespective of how many objects of the class you create.

Apart from these keywords, the final keyword can be used with method arguments as well.

Final Arguments

Arguments are the variable declarations that appear in between the parentheses in a method declaration. A typical method declaration with multiple arguments looks like this:
public String getName(int empNum, int department) {}

Method arguments are essentially the same as local variables. In the preceding example, the variables empNum and department will both follow all the rules applied to local variables. This means they can also have the modifier final:
public String getName (int empNum, final int department) {}

In this example, the variable department is declared as final, which of course means it can’t be modified within the method. In this case, “modified” means reassigning a new value to the variable. In other words, a final argument must keep the same value that the parameter had when it was passed into the method.
i.e.,
public String getName (int empNum, final int department) {
department = 20;
// lots of other code
}
In the above class, the variable department is assigned to a value 20 which cannot be done because the variable is final and you will get a compiler error if you try to compile this piece of code.

Previous Chapter: Chapter 4 - Access Modifiers

Next Chapter - Quick Recap - Chapters 1 to 5

No comments:

Post a Comment

© 2013 by www.inheritingjava.blogspot.com. All rights reserved. No part of this blog or its contents may be reproduced or transmitted in any form or by any means, electronic, mechanical, photocopying, recording, or otherwise, without prior written permission of the Author.

ShareThis

Google+ Followers

Followers