Previous
Index

Next


Chapter 4) Language Fundamentals

Objective 1, Packages, import, inner classes, interfaces

Identify correctly constructed package declarations, import statements, class declarations (of all forms including inner classes) interface declarations, method declarations (including the main method that is used to start execution of a class), variable declarations, and identifiers.

Note on this objective

This is a strangely phrased objective. It seems to be asking you to understand where, how and why you can use import and package statements and where you should place the interface statement and variable statements.

The package statement

The name package implies a collection of classes, somewhat like a library. In use a package is also a little like a directory. If you place a package statement in a file it will only be visible to other classes in the same package. Packages help address the issue of name resolution. There are only so many sensible names you can use for Classes and eventually you may need to use or create a class with the same name. By appending a complete package name before the class you can re-use the same name. The convention for package names is to use the internet domain of the organization creating the class. Thus when creating a class called Question to represent a mock exam question I created the directory structure i used the name of my website domain which is www.jchq.net.

The www portion does not uniquely identify anything of the site so the domain used will be net.jchq. To create the class in my unique package I create a directory jchq and under that I create a directory called net. Within that directory I can then create a class called Question with the following package line at the top

package net.jchq.*;

This will give you access to any class in that package/directory. You might alternatively just specify one class to gain access to with a line like

package net.jchq.Question;

The import statement

Import statements must come after any package statements and before any code. Import statements cannot come within classes, after classes are declared or anywhere else.

The import statement allows you to use a class directly instead of fully qualifying it with the full package name. An example of this is that the classname java.awt.Button is normally referred to simply as Button, so long as you have put in the statement at the top of the file as follows

import java.awt.*;

If I subsequently want to create an instance of my Question class I need to either import the package or specify the full package of the class. To import the package in another class I would need a line that read

import net.jchq.*;

To specify the full package of the class I would need to use the following style of syntax.

jchq.net.Question question = new net.jchqQuestion();

As you can imagine it is a bit dull to constantly have to type the fully qualified package so importing the class is generally the preferred approach.

Note that using an import statement has no impact on performance. It is analogous to setting up a path statement in a DOS (or Unix) environment. It simply sets up the availability or path to the classes, it doesn't actively bring in the code into the program. Only actually using the classes in the program can do anything to impact on performance.

You can place a comment before the package statement but nothing else. You may get exam questions that place an import statement before the package statement

//You can place a comment before the package statement

package MyPack;
public class MyPack{}



The following will cause an error

import java.awt.*;
//Error: Placing an import statement before the package 

//statement will cause a compile time error
package MyPack;
public class MyPack{}

    

Key Concept Logo

If a source file has a package statement, it must come before any other statement apart from comments



The package statement may include the dot notation to indicate a package hierarchy. Thus the following will compile without error

package myprogs.MyPack;

public class MyPack{}

Remember that if you do not place a package statement in a source file it will be considered to have a default package which corresponds to the current directory. This has implications for visibility which is covered in Section 1.2 Declarations and access control.



Class and inner class declarations

A file can only contain one outer public class. If you attempt to create a file with more than one public class the compiler will complain with a specific error. A file can contain multiple non public classes, but bear in mind that this will produce separate .class output files for each class. It does not matter where in the file the public class is placed, so long as there is only one of them in the file.

Inner classes were introduced with JDK 1.1. The idea is to allow one class to be defined within another, to be defined within a method and for the creation of anonymous inner classes. This has some interesting affects, particularly on visibility.


Here is a simple example of an inner class

class Outer{
         class inner{}
}

This results in the generation of class files with the names

Outer.class
Outer$Inner.class

The definition of the inner class is only visible within the context of an existing Outer class. Thus the following will cause a compile time error

class Outer{
          class Inner{}
}

class Another{
public void amethod(){
        Inner i = new Inner();
        }
}

So far as the class Another is concerned, the class Inner does not exist. It can only exist in the context of an instance of the class Outer. Thus the following code works fine because there is an instance of this for the outer class at the time of creation of the instance of Inner

class Outer{
          public void mymethod(){
                  Inner i = new Inner();
          }
          public class Inner{}
}

But what happens if there is no existence of this for the class Outer. To make sense of the rather odd syntax provided for this try to think of the keyword new as used in the above example as belonging to the current insistence of this.

Thus you could change the line that creates the instance of this to read

Inner i = this.new Inner();

Thus if you need to create an instance of Inner from a static method or somewhere else where there is no this object you can use new as a method belonging to the outer class

class Outer{
          public class Inner{}
}

class another{
public void amethod(){
        Outer.Inner i = new Outer().new Inner();
        }
}

Despite my glib explanations, I find this syntax unintuitive and forget it five minutes after learning it. It is very likely that you will get a question on this in the exam, so give it extra attention.

You can gain access to an inner class by using the syntax
Outer.Inner i = new Outer().new Inner();

 

One of the benefits of inner classes is that an inner class generally gets access to the fields of its enclosing (or outer) class. Unlike an outer class, an inner class may be private or static. The examiners seem to like to ask simple questions that boil down to "can an inner class be static or private".

The methods of an static inner class can of course access any static fields of its enclosing class as there will only ever be one instance of any of those fields.

Inner classes declared within methods

Inner classes can be created within methods. This is something that GUI builders like Borland JBuilder do a great deal of when creating Event handlers.

Here is an example of such automatically generated code

buttonControl1.addMouseListener(new java.awt.event.MouseAdapter() {
      public void mouseClicked(MouseEvent e) {
        buttonControl1_mouseClicked(e);
      }
    });



Note the keyword new just after the first parenthesis. This indicates that an anonymous inner class is being defined within the method addMouseListener. This class could have been defined normally with a name which might make it easier for a human to read, but as no processing is done with it anywhere else, having a name does not help much.

If you create such code by hand, it is easy to get confused over the number and level of brackets and parentheses. Note how the whole structure ends with a semi colon, as this is actually the end of a method call.

As you might guess an anonymous class cannot have be given a constructor by the programmer. Think about it, a constructor is a method with no return value and the same name as the class. Duh! we are talking about classes without names. An anonymous class may extend another class or implement a single interface. This peculiar limit does not seem to be tested in the exam.

Field visibility for classes defined within a method

A class defined within a method can only access fields in the enclosing method if they have been defined as final. This is because variables defined within methods normally are considered automatic, ie they only exist whilst the method is executing. Fields defined within a class created within a method may outlive the enclosing method.

A class defined within a method can only access final fields of the enclosing method.



Because a final variable cannot be changed the JVM can be sure that the value will stay constant even after the outer method has ceased to execute. You are very likely to get questions on this in the exam, including questions that query the status of variables passed as a parameter to the method (yes, they too must be final)

Creating an interface

Interfaces are the way Java works around the lack of multiple inheritance. Interestingly Visual Basic uses the keyword interface and uses the concept in a manner similar to Java. The interface approach is sometimes known as programming by contract. An interface is used via the keyword "implements". Thus a class can be declared as

class Malvern implements Hill,Well{
   public 
   }
       

The main method

Because all code in java must exist in in a class, there is a need for a special or "magic" method to cause a program to start running. This method has the signature

public static void main(String argv[])

To take each item of the declaration, the public keyword means the method is visible from just about everywhere. The static part means the method belongs to the class itself rather than any particular instance of the class. This means it can be called without creating an instance of the class. The word void means that it does not return a value. Note that the word main is all lower case. The part between the parenthesis indicates that the method takes a parameter of an array of Strings. Of course the word String must start with an upper case S. The name of the argument arg does not matter, you coul call it bycycle or trousers or any valid variable name and it would still work correctly. However it is a convention worth sticking to to call the parameter arg. Because the square brackets of an array can come after the name or the type is also acceptable to declare the parameter as String [] arg.

Note this is the correct signature for the purpose of the Sun Certified Java Programmers Exam. You may find that other similar signatures will work in reality but for the exam (and future compatibility purposes) you should use that signature. Because this method is static it does not require an instance of the class to be created to cause it to be called (or effectivly triggered by the Java environment). Also not that because it is static you cannot manipulate non static methods or data. Because of this the main method often contains very little code, typically it contains code to create an instance of the enclosing class and then a call to a non static method that really gets the program to do its work.

The String array that gets passed to the main method by the system contains any parameters that were passed on the command line when the program is started. Of course with modern gui environments it is more common to start a program by clicking on an icon with no change to pass anyparameters.



Objective 4.2 of the exam specifically requires you to understand how the command line parameters are passed to the main method and how you can access them. Thus it says..

State the correspondence between index values in the argument array passed to a main method and command line arguments.

Questions

Question 1)

Given the following code

public class FinAc{
        static int l = 4;
        private int k=2;

public static void main(String argv[]){
        FinAc a = new FinAc();
        a.amethod();
        }

     public void amethod(){
        final int i = 99;
        int j = 6;
        class CInMet{
                public void mymethod(int q){
                                //Here
                     }//end of mymethod
                }//End of CInMet

                CInMet c = new CInMet();
                c.mymethod(i);
     }//End of amthod
}



Which of the following variables are visible on the line marked with the comment //Here?

1) l
2) k
3) i
4) j


Question 2)

Which of the following will compile correctly?

1)

//A Comment

import java.awt.*;

class Base{};

2)

import java.awt.*;
package Spot;
class Base();

3)

//Another comment

package myprogs.MyPack;
public class MyPack{}

4)

class Base{}
import java.awt.*;
public class Tiny{}

Question 3)

Which of the following statements are true?

1) An inner class may be defined as static
2) An inner class may NOT be define as private
3) An anonymous class may have only one constructor
4) An inner class may extend another class


Question 4)

From code that has no current this reference how can you create an instance of an inner class?

1) Outer.Inner i = new Outer().new Inner(); 2) Without a this reference an inner class cannot be created
3) Outer.Inner i = Outer().new new Inner();
4) Outer i = Outer.new().Inner();

Question 5)

Which of the following are correctly form main methods to start execution of a Java program?

1) public static void main(String[] bicycle);
2) public void main(String argv[]);
3) public static int main(String args[])
4) public static void main(String args[]);

Question 6

What will happen when you attempt to compile the following code?

abstract class Base{
    abstract public void getValue(Base b);
    
}
public class Robinwood extends Base{
    public static void main(String argv[]){
    Robinwood rw = new Robinwood();
    rw.main();
    }
    public void main(){
    getValue(this);
    }
    public void getValue(Base b){
        
    }
}

1) Compile error, only methods can be marked as abstract
2) Compile error, the name "main" is reserved for the startup method
3) Compile error, the parameter to the getValue call is of the wrong type
4) Compilation without error

       

Question 7)

// located in the East end
package spital;

abstract class Spital{
public Spital(int i){}
}
public class Mudchute extends Spital{
    public static void main(String argv[]){

    Mudchute ms = new Mudchute();
    ms.go();
    }
    public  Mudchute(){
    super(10);
    }
    public void go(){
    island();

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

}

1) Compile time error, any package declaration must appear before anything else
2) Output of 10 followed by island
3) Output of 10 followed by "spital island"
4) Compile time error

Question 8)

For a class defined inside a method, what rule governs access to the variables of the enclosing method?

1 ) The class can access any variable
2) The class can only access static variables
3) The class can only access transient variables
4) The class can only access final variables



Answers

Answer 1)

1) l
2) k
3) i
A class defined within a method can only see final fields from its enclosing method. However it can see the fields in its enclosing class including private fields. The field j was not defined as final.

Answer 2)

1)

//A Comment
import java.awt.*;
class Base{};

3)

//Another comment

package myprogs.MyPack;
public class MyPack{}



Any package statement must be the first item in a file (apart from comments). An import statement must come after any package statement and before any code.


Answer 3)

1) An inner class may be defined as static
4) An inner class may extend another class

How could an anonymous class have a constructor? Inner classes may be defined as private.


Answer 4)

1) Outer.Inner i = new Outer().new Inner();

Answer 5)

1) public static void main(String[] bicycle);
4) public static void main(String args[]);

Option 2 will compile, but will not act as the startup method for program because it is not declared as static. Option 3 will not compile because it is declared as returning an int value.

Answer 6

4) Compilation without error

Giving the name "main" to a method other than the startup method is syntactically correct but very poor style. Because the class Robinwood extends the class Base it is possible to use it as a parameter to a method that is expecting a parameter of type Base

Answer 7

2) Output of 10 followed by island

A package declaration must appear before anything except comments, which can appear just about anywhere.

Answer 8

The class can only access final variables

Note that this restriction applies to variables in the enclosing method, not the enclosing class


Other sources on this topic

The Sun Tutorial
http://java.sun.com/docs/books/tutorial/java/javaOO/QandE/nested-questions.html

NASA
http://tinf2.vub.ac.be/~dvermeir/java/other_doc/JavaPackages.html

JavaRanch
http://www.javaranch.com/campfire/StoryInner.jsp

Eric Dofonsou
http://www3.sympatico.ca/wrickd/computers/articles/innerclasses.html

Mughal and Rasumussen: Language fundamentals
http://www.ii.uib.no/~khalid/pgjc/jcbook/PGJC-ch02.pdf

Jyothi Krishnan on this topic at

http://www.geocities.com/SiliconValley/Network/3693/obj_sec4.html#obj9

The Java Language Specification on interfaces
http://java.sun.com/docs/books/jls/second_edition/html/interfaces.doc.html




Previous
Index

Next