Return to Tutorial Index

Back to the home page of this site

Java2 Certification
Tutorial

 

You can discuss this topic with others at http://www.jchq.net/discus
Read reviews and buy a Java Certification book at http://www.jchq.net/bookreviews/jcertbooks.htm


1) Declarations and Access Control

Objective 2

Declare classes, inner classes, methods, instance variables static, variables and automatic (method local) variables, making appropriate use of all permitted modifiers (such as public final static abstract and so forth). State the significance of each of these modifiers both singly and in combination and state the effect of package relationships on declared items qualified by these modifiers.

Comment on the objective

I find it a little disturbing that the objective uses the words "and so forth".
I suspect this means you should also be aware of

Comparing C++/VB classes with Java

Because Java was designed to be easy for C++ programmers to learn there are many similarities between the way the two languages deal with classes. Both C++ and Java have inheritance, polymorphism, and data hiding using visibility modifiers. Some of the ways in which they differ are to do with making Java an easier language to learn and use.

The C++ language implements multiple inheritance and thus a class can have more than one parent (or base) class. Java allows only single inheritance and thus can only ever have a single parent. To overcome this limitation Java has a feature called interfaces. The language designers decided that interfaces would give some of the benefits of multiple inheritance without the drawbacks. All Java classes are descendants of the great ancestor class called Object.

Objects in Visual Basic are somewhat of a bolt on afterthought to the language. Visual Basic is sometimes called an Object Based language rather than Object Oriented. It is almost as if the language designers decided that classes are cool and with VB version 4 decided that they would create a new type of module, call it a class and use the dot notation to make it more like C++. The crucial element missing from the VB concept of class is that of inheritance. With VB5 Microsoft delivered the concept of interfaces which acts similarly to the Java concept of an interface. Some of the main similarities between VB classes and Java classes is the use of references and the keyword new word.

The role of classes in Java

Classes are the heart of Java, all Java code occurs within a class. There is no concept of free standing code and even the most simple HelloWorld application involves the creation of a class. To indicate that a class is a descendent of another class the extends keyword is used. If the extends keyword is not used the class will be a descended of the base class Object, which gives it some basic functionality including the ability to print out its name and some of the capability required in threads.

The simplest of class

The minimum requirements to define a class are the keyword class, the class name and the opening and closing braces. Thus

class classname {}

is a syntactically correct, if not particularly useful class (surprisingly I have found myself defining classes like this, when creating examples to illustrate inheritance).

Normally a class will also include an access specifier before the keyword class and of course, a body between the braces. Thus this is a more sensible template for a class.

public class classname{
//Class body goes here
}

Creating a simple HelloWorld class

Here is a simple HelloWorld program that will output the string "hello world" to the console.

public class HelloWorld{
public static void main(String argv[]){
        System.out.println("Hello world");
        }

}//End class definition

The keyword public is a visibility modifier that indicates this class should be visible to any other class. Only one outer class per file can be declared public. Inner classes will be covered elsewhere. If you declare more than one class in a file to be public, a compile time error will occur. Note that Java is case sensitive in every respect. The file that contains this class must be called HelloWorld.Java. Of course this is somewhat of an anomaly on Microsoft platforms that preserve, yet ignore the case of letters in a file name.

The keyword class indicates that a class is about to be defined and HelloWorld is the name of that class. The curly braces indicate the start of the class. Note that the closing brace that ends the class definition does not involve any closing semi colon. The comment

//End class definition 

uses the style of single line comments that is available in C/C++. Java also understands the multi-line /* */ form of comments.

The magic of the main name

Giving a method the following signature has a certain significance (or magic) as it indicates to Java that this is where the program should begin its run, (similar to main in the C language).

public static void main(String argv[]){

This line indicates that a method called main is being defined that takes arguments (or parameters) of an array of Strings. This method is public, i.e. visible from anywhere that can see this class. The static keyword indicates that this method can be run without creating an instance of the class. If that means nothing to you, don't worry about it for the moment as static methods will be covered at length elsewhere. The keyword void indicates the data type returned from this method when it is called. The use of void indicates that no value will be returned.

The parameters of the main method

String argv[] 

Indicate that the method takes an array of type String. The square brackets indicate an array. Note that the data type String starts with an upper case S. This is important as Java is thoroughly case sensitive. Without this exact signature the Java Virtual Machine will not recognise the method as the place to start execution of the program.

Creating an instance of a class

The HelloWorld application as described above is handy to illustrate the most basic of applications that you can create, but it misses out on one of the most crucial elements of using classes, the use of the key word


new

Which indicates the creation of a new instance of a class. In the HelloWorld application this was not necessary as the only method that was called was System.out.println, which is a static method and does not require the creation of a class using the new keyword. Static methods can only access static variables, of which only one instance can exist per class. The HelloWorld application can be slightly modified to illustrate the creation of a new instance of a class.

public class HelloWorld2{
        public static void main(String argv[]){        
                HelloWorld2 hw = new HelloWorld2();
                hw.amethod();
        }
       
        public void amethod(){        
                System.out.println("Hello world");
        }

}

This code creates a new instance of itself with the line

                HelloWorld2 hw = new HelloWorld2();

This syntax of creating a new instance of a class is basic to the use of classes. Note how the name of the class appears twice. The first time indicates the data type of the reference to the class. This need not be the same as the actual type of the class as indicated after the use of the new keyword. The name of this instance of the class is hw. This is simply a name chosen for a variable. There is a naming convention that an instance of a class starts with a lower case letter, whereas the definition of a class starts with an upper case letter.

The empty parenthesis for the name of the class HelloWorld() indicate that the class is being created without any parameters to its constructor. If you were creating an instance of a class that was initialized with a value or a string such as the label of a button the parenthesis would contain one or more initializing values.

Creating Methods

As illustrated in the last example HelloWorld2, a method in Java is similar to a function in C/C++ and a function or sub in Visual Basic. The method called amethod in that example is the method called amethod in this example is declared as

public

To indicate it can be accessed from anywhere. It has a return type of


void

indicating no value will be returned. And it has empty parenthesis, indicating that it takes no parameters.


The same method might have been defined in these alternative ways

private void amethod(String s)

private void amethod(int i, String s)

protected void amethod(int i)

These examples are to illustrate some other typical signatures of methods. The use of the keywords private and protected will be covered elsewhere.

The difference between Java methods and methods in a non OO language such as C is that the methods belong to a class. This means they are called using the dot notation indicating the instance of the class that the code belongs to. (Static methods are an exception to this but don't worry about that at the moment).

Thus in HelloWorld2 amethod was called thus

                HelloWorld hw = new HelloWorld()
                hw.amethod();

If other instances of the HelloWorld class had been created the method could have been called from each instance of the class. Each instance of the class would have access to its own variables. Thus the following would involve calling the amethod code from different instances of the class.

HelloWorld hw = new HelloWorld();
HelloWorld hw2 = new HelloWorld();
hw.amethod();
hw2.amethod();

The two instances of the class hw and hw2 might have access to different variables.

Automatic variables

Automatic variables are method variables. They come into scope when the method code starts to execute and cease to exist once the method goes out of scope. As they are only visible within the method they are typically useful for temporary manipulation of data. If you want a value to persist between calls to a method then a variable needs to be created at class level.

An automatic variable will "shadow" a class level variable.


Thus the following code will print out 99 and not 10.

public class Shad{
public int iShad=10;
public static void main(String argv[]){
                Shad s = new Shad();
                s.amethod();
        }//End of main
        public void amethod(){
                int iShad=99;
                System.out.println(iShad);
        }//End of amethod
}

Modifiers and encapsulation

The visibility modifiers are part of the encapsulation mechanism for Java. Encapsulation allows separation of the interface from the implementation of methods.

The visibility modifiers are a key part of the encapsulation mechanism for java. Encapsulation allows separation of the interface from the implementation of methods. The benefit of this is that the details of the code inside a class can be changed without it affecting other objects that use it. This is a key concept of the Object Oriented paradaigm (had to use that word somewhere eventually).

Encapsulation generally takes form of methods to retrieve and update the values of private class variables. These methods are known as a accessor and mutator methods. The accessor (or get) method retrieves the value and the mutator changes (or sets) the value. The naming convention for these methods are setFoo to change a variable and getFoo to obtain the contents of a variable. An aside note: the use of get and set in the naming of these methods is more significant than just programmer convenience and is an important part of the Javabeans system. Javabeans are not covered in the programmer exam however.

Take the example where you had a variable used to store the age of a student.

You might store it simply with a public integer variable

int iAge;

later when your application is delivered you find that some of your students have a recorded age of more than 200 years and some have an age of less than zero. You are asked to put in code to check for these error conditions. So wherever your programs change the age value, you write if statements that check for the range.

if(iAge > 70){
        //do something
        }
if (iAge <3){
        //do something
}

In the process of doing this you miss some code that used the iAge variable and you get called back because you have a 19 year old student who is on your records has being 190 years old.

The Object Oriented approach to this problem using encapsulation, is to create methods that access a private field containing the age value, with names like setAge and getAge. The setAge method might take an integer paramete and update the private value for Age and the getAge method would take no parameter but return the value from the private age field.

public void setAge(int iStudentAge){
        iAge = iStudentAge;
}

public int getAge(){
        return iAge;
}

At first this seems a little pointless as the code seems to be a long way around something that could be done with simple variable manipulation. However when they come back to you with the requirement to do more and more validation on the iAge field you can do it all in these methods without affecting existing code that uses this information.

By this approach the implementation of code, (the actual lines of program code), can be changed whilst the way it looks to the outside world (the interface) remains the same.

 

Private

Private variables are only visible from within the same class as they are created.in. This means they are NOT visible within sub classes. This allows a variable to be insulated from being modified by any methods except those in the current class. As described in modifiers and encapsulation, this is useful in separating the interface from the implementation.

class Base{
private int iEnc=10;
public void setEnc(int iEncVal){
     if(iEncVal < 1000){
         iEnc=iEncVal;
          }else
          System.out.println("Enc value must be less than 1000");
         //Or Perhaps thow an exception
        }//End if
}

public class Enc{
public static void main(String argv[]){
                Base b = new Base();
                b.setEnc(1001);
        }//End of main
}

Public

The public modifier can be applied to a variable (field) or a class. It is the first modifier you are likely to come across in learning Java. If you recall the code for the HelloWorld.Java program the class was declared as

public class HelloWorld

This is because the Java Virtual Machine only looks in a class declared as public for the magic main startup method

public static void main(String argv[])

A public class has global scope, and an instance can be created from anywhere within or outside of a program. Only one non inner class in any file can be defined with the public keyword. If you define more than one non inner class in a file with the keyword public the compiler will generate an error.

Using the public modifier with a variable makes it available from anywhere. It is used as follows,

public int myint =10;

If you want to create a variable that can be modified from anywhere you can declare it as public. You can then access it using the dot notation similar to that used when calling a method.

class Base {
        public int iNoEnc=77;
}
public class NoEnc{
public static void main(String argv[]){
                Base b = new Base();
                b.iNoEnc=2;
                System.out.println(b.iNoEnc);
        }//End of main
}

Note that this is not the generally suggested way as it allows no separation between the interface and implementation of code. If you decided to change the data type of iNoEnc, you would have to change the implementation of every part of the external code that modifies it.

Protected

The protected modifier is a slight oddity. A protected variable is visible within a class, and in sub classes, the same package but not elsewhere. The qualification that it is visible from the same package can give more visibility than you might suspect. Any class in the same directory is considered to be in the default package, and thus protected classes will be visible. This means that a protected variable is more visible than a variable defined with no access modifier.

A variable defined with no access modifier is said to have default visibility. Default visibility means a variable can be seen within the class, and from elsewhere within the same package, but not from sub-classes that are not in the same package.

Static

Static is not directly a visibility modifier, although in practice it does have this effect. The modifier static can be applied to an inner class, a method and a variable. Marking a variable as static indicates that only one copy will exist per class. This is in contrast with normal items where for instance with an integer variable a copy belongs to each instance of a class. Thus in the following example of a non static integer three instances of the integer iMyVal will exist and each instance can contain a different value.

class MyClass{
        public int iMyVal=0;
}
public class NonStat{
public static void main(String argv[]){
        MyClass m1 = new MyClass();
        m1.iMyVal=1;
        MyClass m2 = new MyClass();
        m2.iMyVal=2;
        MyClass m3 = new MyClass();
        m3.iMyVal=99;
        //This will output 1 as each instance of the class
        //has its own copy of the value iMyVal
        System.out.println(m1.iMyVal);
        }//End of main

}


The following example shows what happens when you have multiple instances of a class containing a static integer.

class MyClass{
        public static  int iMyVal=0;

}//End of MyClass
public class Stat{
public static void main(String argv[]){
           MyClass m1 = new MyClass();
           m1.iMyVal=0;
           MyClass m2 = new MyClass();
           m2.iMyVal=1;
           MyClass m3 = new MyClass();
           m2.iMyVal=99;
           //Because iMyVal is static, there is only one 
           //copy of it no matter how many instances 
           //of the class are created /This code  will 
           //output a value of 99
           System.out.println(m1.iMyVal);
        }//End of main

}

Bear in mind that you cannot access non static variables from within a static method. Thus the following will cause a compile time error

public class St{
int i;
public static void main(String argv[]){
        i = i + 2;//Will cause compile time error
        }
}

Key Concept

A static method cannot be overriden to be non static in a child class

A static method cannot be overriden to be non static in a child class. Also a non static (normal) method cannot be overriden to be static in a child class. There is no similar rule with reference to overloading. The following code will cause an error as it attempts to override the class amethod to be non-static.

class Base{
        public static void amethod(){
        }
}

public class Grimley extends Base{
        public void amethod(){}//Causes a compile time error
}

The IBM Jikes compiler produces the following error

Found 1 semantic error compiling "Grimley.java":

     6.         public void amethod(){}

                            <------->

*** Error: The instance method "void amethod();" 

cannot override the static method "void amethod();" 

declared in type "Base"

Native

The native modifier is used only for methods and indicates that the body of the code is written in a language other than Java such as C and C++. Native methods are often written for platform specific purposes such as accessing some item of hardware that the Java Virtual Machine is not aware of. Another reason is where greater performance is required.

A native method ends with a semicolon rather than a code block. Thus the following would call an external routine, written perhaps in C++

public native fastcalc();

Abstract

It is easy to overlook the abstract modifier and miss out on some of its implications. It is the sort of modifier that the examiners like to ask tricky questions about.

The abstract modifier can be applied to classes and methods. When applied to a method it indicates that it will have no body (ie no curly brace part) and the code can only be run when implemented in a child class. However there are some restrictions on when and where you can have abstract methods and rules on classes that contain them. A class must be declared as abstract if it has one or more abstract methods or if it inherits abstract methods for which it does not provide an implementation. The other circumstance when a class must be declared abstract is if it implements an interface but does not provide implementations for every method of the interface. This is a fairly unusual circumstance however.

If a class has any abstract methods it must be declared abstract itself.

Do not be distracted into thinking that an abstract class cannot have non abstract methods. Any class that descends from an abstract class must implement the abstract methods of the base class or declare them as abstract itself. These rules tend to beg the question why would you want to create abstract methods?

Abstract methods are mainly of benefit to class designers. They offer a class designer a way to create a prototype for methods that ought to be implemented, but the actual implementation is left to people who use the classes later on. Here is an example of an abstract a class with an abstract method. Again note that the class itself is declared abstract, otherwise a compile time error would have occurred.

The following class is abstract and will compile correctly and print out the string

public abstract class abstr{
public static void main(String argv[]){
        System.out.println("hello in the abstract");
        }
        public abstract int amethod();
}

 

Final

The final modifier can be applied to classes, methods and variables. It has similar meanings related to inheritance that make it fairly easy to remember. A final class may never be subclassed. Another way to think of this is that a final class cannot be a parent class. Any methods in a final class are automatically final. This can be useful if you do not want other programmers to "mess with your code". Another benefit is that of efficiency as the compiler has less work to do with a final method. This is covered well in Volume 1 of Core Java.

The final modifier indicates that a method cannot be overriden. Thus if you create a method in a sub class with exactly the same signature you will get a compile time error.

The following code illustrates the use of the final modifier with a class. This code will print out the string "amethod"

final class Base{

public void amethod(){
        System.out.println("amethod");
        }
}

public class Fin{
public static void main(String argv[]){
        Base b = new Base();
        b.amethod();
        }
}

A final variable cannot have it's value changed and must be set at creation time. This is similar to the idea of a constant in other languages.

Synchronized

The synchronized keyword is used to prevent more than one thread from accessing a block of code at a time. See section 7 on threads to understand more on how this works.

Transient

The transient keyword is one of the less frequently used modifiers. It indicates that a variable should not be written out when a class is serialized.

Volatile

You probably will not get a question on the volatile keyword. The worst you will get it is recognising that it actually is a Java keyword. According to Barry Boone

"it tells the compiler a variable may change asynchronously due to threads"

Accept that it is part of the language and then get on worrying about something else

Using modifiers in combination

The visibility modifiers cannot be used in combination, thus a variable cannot be both private and public, public and protected or protected and private. You can of course have combinations of the visibility modifiers and the modifiers mentioned in my so forth list

Thus you can have a public static native method.

Where modifiers can be used

Modifier

Method

Variable

class

public

yes

yes

yes

private

yes

yes

yes (nested)

protected

yes

yes

yes(nested)

abstract

yes

no

yes

final

yes

yes

yes

transient

no

yes

no

native

yes

no

no

volatile

no

yes

no


Exercise 1)

Create a file called Whitley.java. In this file define a class called Base with an abstract method called lamprey with an int return type. In this file create a class called Whitley that extends the base class. Give the Whitley class a method called lamprey and code that prints out the string "lamprey"..

Create a native method for the class called mynative. Now compile and run the code.

Exercise 2)

Create a public class called Malvern. Create a private inner class called Great that has a public void method called show. Make this method print out the string "Show". Give the class Malvern a public method called go that creates an instance of Great and calls its show method.. In the main method of Malvern create an instance of itself. Make the instance of itself call its go method. Compile and run the code.


Suggested solution to Exercise 1)

abstract class Base{
abstract int lamprey();
}

public class Whitley extends Base{
public static void main(String argv[]){
        
        }

public int lamprey(){
        System.out.println("lamprey");
        return 99;
        }
native public void mynative();
}

Suggested solution to Exercise 2)

public class Malvern{
public static void main(String argv[]){
        Malvern m = new Malvern();
        m.go();
        }
        public void go(){
        Great g = new Great();
        g.show();
        }

        private class Great{
                public void show(){
                        System.out.println("Show");     
                }
        }
}

 


Questions

Question 1)

What will happen when you attempt to compile and run this code?

abstract class Base{
        abstract public void myfunc();
        public void another(){
        System.out.println("Another method");
        }
}

public class Abs extends Base{
        public static void main(String argv[]){
        Abs a = new Abs();
        a.amethod();
        }
        public void myfunc(){
                System.out.println("My func");
                } 

        public void amethod(){
        myfunc();
         }
}

1) The code will compile and run, printing out the words "My Func"
2) The compiler will complain that the Base class has non abstract methods
3) The code will compile but complain at run time that the Base class has non abstract methods
4) The compiler will complain that the method myfunc in the base class has no body, nobody at all to looove it




Question 2)

What will happen when you attempt to compile and run this code?

public class MyMain{
public static void main(String argv){
        System.out.println("Hello cruel world");
        }
}

1) The compiler will complain that main is a reserved word and cannot be used for a class
2) The code will compile and when run will print out "Hello cruel world"
3) The code will compile but will complain at run time that no constructor is defined
4) The code will compile but will complain at run time that main is not correctly defined




Question 3)

Which of the following are Java modifiers?

1) public
2) private
3) friendly
4) transient


Question 4)

What will happen when you attempt to compile and run this code?

class Base{
        abstract public void myfunc();
        public void another(){
        System.out.println("Another method");
        }
}

public class Abs extends Base{
        public static void main(String argv[]){
        Abs a = new Abs();
        a.amethod();
        }
        public void myfunc(){
                System.out.println("My func");
                } 
        public void amethod(){
        myfunc();
        }

}

1) The code will compile and run, printing out the words "My Func"
2) The compiler will complain that the Base class is not declared as abstract.
3) The code will compile but complain at run time that the Base class has non abstract methods
4) The compiler will complain that the method myfunc in the base class has no body, nobody at all to looove it


Question 5)

Why might you define a method as native?

1) To get to access hardware that Java does not know about
2) To define a new data type such as an unsigned integer
3) To write optimised code for performance in a language such as C/C++
4) To overcome the limitation of the private scope of a method




Question 6)

What will happen when you attempt to compile and run this code?

class Base{
public final void amethod(){
        System.out.println("amethod");
        }
}

public class Fin extends Base{
public static void main(String argv[]){
        Base b = new Base();
        b.amethod();
        }
}

1) Compile time errror indicating that a class with any final methods must be declared final itself
2) Compile time error indicating that you cannot inherit from a class with final methods
3) Run time error indicating that Base is not defined as final
4) Success in compilation and output of "amethod" at run time.




Question 7)

What will happen when you attempt to compile and run this code?

public class Mod{
public static void main(String argv[]){
}
        public static native void amethod();
}

1) Error at compilation: native method cannot be static
2) Error at compilation native method must return value
3) Compilation but error at run time unless you have made code containing native amethod available
4) Compilation and execution without error





Question 8)

What will happen when you attempt to compile and run this code?

private class Base{}
public class Vis{
transient int  iVal;
public static void main(String elephant[]){
        }
}

1) Compile time error: Base cannot be private
2) Compile time error indicating that an integer cannot be transient
3) Compile time error transient not a data type
4) Compile time error malformed main method




Question 9)

What happens when you attempt to compile and run these two files in the same directory?

//File P1.java
package MyPackage;
class P1{
void afancymethod(){
        System.out.println("What a fancy method");
        }
}
//File P2.java
public class P2 extends P1{
afancymethod();
}

1) Both compile and P2 outputs "What a fancy method" when run
2) Neither will compile
3) Both compile but P2 has an error at run time
4) P1 compiles cleanly but P2 has an error at compile time


Question 10)

Which of the following are legal declarations?

1) public protected amethod(int i)
2) public void amethod(int i)
3) public void amethod(void)
4) void public amethod(int i)


Answers

Answer 1)

1) The code will compile and run, printing out the words "My Func"

An abstract class can have non abstract methods, but any class that extends it must implement all of the abstract methods.

Answer 2)

4) The code will compile but will complain at run time that main is not correctly defined

The signature of main has a parameter of String rather than string array


Answer 3)

1) public
2) private
4) transient

Although some texts use the word friendly when referring to visibility it is not a Java reserved word. Note that the exam will almost certainly contain questions that ask you to identify Java keywords from a list

Answer 4)

2) The compiler will complain that the Base class is not declared as abstract.

The actual error message using my JDK 1.1 compiler was

Abs.java:1: class Base must be declared abstract. 

It does not define void myfunc

() from class Base.

class Base{

^

1 error

Answer 5)

1) To get to access hardware that Java does not know about
3) To write optimised code for performance in a language such as C/C++

Although the creation of "Pure Java" code is highly desirable, particularly to allow for platform independence, it should not be a religion, and there are times when native code is required.

Answer 6)

4) Success in compilation and output of "amethod" at run time.

This code calls the version of amethod in the Base class. If you were to attempt to implement an overriden version of amethod in Fin you would get a compile time error.

Answer 7)

4) Compilation and execution without error

There is no call to the native method and so no error occurs at run time

Answer 8)

1) Compile time error: Base cannot be private

A top level class such as base cannot be declared to be private.

Answer 9)

4) P1 compiles cleanly but P2 has an error at compile time

Even though P2 is in the same directory as P1, because P1 was declared with the package statement it is not visible from P2


Answer 10)

2) public void amethod(int i)

If you thought that option 3 was legal with a parameter argument of void you may have to empty some of the C/C++ out of your head.
Option 4) is not legal because method return type must come immediatly before the method name.


Other sources on this topic

This topic is covered in the Sun Tutorial at
Class modifiers
http://java.sun.com/docs/books/tutorial/reflect/class/getModifiers.html
Controlling access to members of a class
http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html

Richard Baldwin Covers this topic at
http://www.Geocities.com/Athens/Acropolis/3797/Java040.htm

Jyothi Krishnan on this topic at
http://www.geocities.com/SiliconValley/Network/3693/obj_sec1.html#obj2

Bruce Eckel Thinking in Java
http://codeguru.earthweb.com/java/tij/tij0056.shtml

Last updated
30 October 2001
copyright © Marcus Green 2001
most recent copy at http://www.jchq.net

End of document