Classes, Part 2: CS 310 Lecture notes 
  
  
     
  
Outline 
  
  
 Scope
  
  Packages and class path.
  
  Comments and Javadoc.
    
Source Program Structure 
  
  
 Java source comprises one or more source files.
    
    
 A source file is your basic text file. 
    
  The filename should have a .java extension.
      
  
  Each source file contains one or more class definitions (among other
  things).
  
  Each class in a source file compiles in to a separate .class file.
    
Executable Structure 
  
  
 The JVM builds an executable from .class files.
    
    
 .class files are loaded at runtime as needed.
    
  This is known as lazy link and load. 
      
  
  This is an amazingly powerful and dangerous feature.
    
    
 Unfortunately, we won’t be pursuing it in this class. 
      
  
  
Compilation 
  
  
 The javac compiler also deals with .class files.
    
    
 It needs them for type checking, for example. 
      
  
  The compiler manages source-.class file consistency automatically.
    
    
 Newer source files are compiled to update older (or nonexistent)
    .class files.
      
  
  
Development Structure 
  
  
 What kind of development structure works well with Java?
    
    
 The trick here is there are two set of files: the source and the
    .class files. 
    
  But this is no different from the source-object (.o) 
file distinction 
    in C-C++.
      
  
  One possibility is a monolithic structure: all files in one place.
    
Monolithic Problems 
  
  
 Monoliths are not well structured, and so don’t scale well and are
  difficult to deal with.
  
  Break monoliths up into interacting pieces.
    
  
  The result is a set of mini-monoliths.
    
    
 But each new monolith is smaller and functionally consistent.
      
  
  
Packages 
  
  
 A package a named group 
    of .class files.
    
    
 Every .class file is a member of exactly one package. 
      
  
  A source file declares package membership with a package
  statement:
package package-name ;
 
    
    
 Every .class file created from the source file belongs to the
    declared package.
      
  
  
Accessing Classes 
  
Class Access 
  
  
 You tell the compiler (and the JVM) the package holding the class.
  
  Package qualification 
<package-name >.<class-name >
board.TetrisBoard board;
 
    
    
 The TetrisBoard .class file in the board package.
      
  
  Almost every class reference has to be package qualified.
    
Scope 
  
  
 Can a class access any other class in any other package?
  
  Scope 
    
 An existent and accessible feature is called in-scope 
  A non-existent or inaccessible feature is called
    out-of-scope   
  
  
Scopes So Far 
  
  
 Packages, classes, and methods are the scopes seen so far.
    
    
 There are others to come.
      
  
  The features introduced so far are packages, classes, methods, and
  field variables.
    
    
 There are others to come.
      
  
  
The General Questions 
  
  
 Can feature X  in scope Y  be accessed from scope Z ?
    
  
  How can scope Z  be prohibited from accessing feature X  in
  scope Y ?
    
    
 This is an important question. 
      
  
  The combinatorics of these questions are complex.
    
Package Scope and Classes 
  
  
 By default, each class in package X  can access any class in
  package X .
    
    
 Accessed by using just the class name. 
      
      
 Package qualification optional. 
        
    
  The compiler defaults to searching the containing package for other
    classes.
      
  
  By default, classes not in package X  cannot access any class in
  package X .
  
  This is the default package scope   
Package Scope Example. 
$ ls
A  B
$ ls A
C1.java
$ ls B
C2.java
$  
 
 
  
 
Package Scope Example.. 
$ cat A/C1.java 
package A;
class C1 { }
$ cat B/C2.java
package B;
class C2 { }
class C3 { 
  B.C2 c2;
  C2 c3;  
  A.C1 c1; 
  }
$  
 
 
  
 
Package Scope Example... 
$ javac B/C2.java
B/C2.java:8: A.C1 is not public in A; 
cannot be accessed from outside package
  A.C1 c1;
   ^
1 error
$  
Package Scope Example.... 
$ cat A/C1.java 
package A;
class C1 { }
$ cat B/C2.java
package B;
class C2 { }
class C3 { 
  B.C2 c2;
  C2 c3;
  A.C1 c1;
  }
$  
 
 
  
 
Widening Package Scope 
  
  
 Default package scope is too restrictive.
    
    
 Cross-package accesses are essential.
      
  
  The public scope public class 
  A public class starts with the public keyword.
    
    
 Public scope is a per-class scope, not per-package. 
      
  
  
Public Class Naming 
  
  
 The name of the source file containing a public class must be the same
  as the public-class name.
$ cat t.java
public class T { }
$ javac t.java
t.java:1: class T is public, 
should be declared in a file named T.java
public class T { }
       ^
1 error
$  
  
  Only one public class per source file.
    
Public Scope Example. 
$ ls
A  B
$ ls A
C1.java
$ ls B
C2.java
$  
 
  
 
Public Scope Example.. 
$ cat A/C1.java 
package A;
public  class C1 { }
$ cat B/C2.java
package B;
class C2 { }
class C3 { 
  B.C2 c2;
  C2 c3;  
  A.C1 c1; 
  }
$  
 
  
 
Public Scope Example... 
$ javac B/C2.java
$  
Observations 
  
  
 A class has either public or package scope.
    
    
 All or nothing access is clumsy.
      
  
  Package scope is global within the package.
    
    
 Every class in the package can access every other class in the
    package.
    
  Problems with this suggest design errors. 
      
      
 In particular, the package’s too big. 
        
    
  
  
  
The Default Package 
  
  
 Every .class file is a member of some package.
$ cat A/C1.java
class C1 { }
$  
  
  package statements are optional.  What package is C1 in?
  
  Classes not explicitly placed in a package fall into the nameless
  default package   
Abbreviating Package Qualification 
  
  
 Every non-local class access has to be package qualified, which is a
  pain. 
  
  The import statement explicitly locates a class.
import package-qualified-class ;
 
  
  Imported classes don’t need package qualification. 
    
    
 Identically named classes from different packages still need package
    qualification. 
      
  
  
Import Example 
$ cat B/C2.java
import A.C1; 
class C2 { }
class C3 { 
  C2 c2;
  C2 c3;  
  C1 c1; 
  }
$ javac B/C2.java
$  
 
  
 
Global Imports 
  
  
 Import statements of the form
import package .*;
 
  import every public class from the given package.
  
  There’s some documentation value to importing individual classes.
    
    
 With a good IDE it doesn’t much matter.
      
  
  * imports could lead to unnecessary name clashes.
    
Mapping Packages 
  
  
 What is a package in the real world?
  
  A package maps naturally to directory in a file system.
    
    
 Mapping to directories is not required, but is the most conventional
    and convenient.
      
  
  Package tetris maps to the directory tetris.
    
    
 This mapping is most natural, but not required. 
      
  
  
!! Warning !! Warning !! 
  
  
 As the general semanticists remind: the map is not the territory.
  
  Do not confuse directories and packages.
    
    
 They are different but related things. 
      
  
  In particular, not every class in a directory is part of the same
  package.
  
  javac 
does not check 
  to see that a source file in a package is being compiled in the proper
  directory for the package.
    
Package Mismapping Example 
   
$ cat A/C1.java
package B;
class C1 { }
$ javac -Xlint A/C1.java
$ ls A
C1.class  C1.java
$  
 
Package Mapping Example. 
   
$ ls
A
$ ls A
C1.java
C2.java
$  
 
Package Mapping Example.. 
   
$ cat A/C1.java 
package A;
class C1 { }
$ cat A/C2.java
class C2 { C1 c1; }
$  
 
Package Mapping Example... 
$ javac A/C2.java
A/C2.java:1: cannot find symbol
symbol  : class C1
location: class C2
class C2 { C1 c1; }
           ^
1 error
$  
   
   
 Even though they share the A directory, both packages are
   separate.
     
Package Mapping Example.... 
   
   
 However,
$ cat A/C2.java
class C2 { A.C1  c1; }
$ javac -Xlint -classpath .. A/C2.java
$  
   
  This can’t be reversed: C1 can’t access C2. 
     
     
 Only default package entities can access default package entities.
     
Why ?
       
   
  
Hierarchical Packages 
  
  
 Packages nest to form a tree structure.
    
    
 Package levels are separated by a dot.
package tetris;
package tetris.player.computer;
 
    
  
  
  Package hierarchies map naturally to file-system hierarchies.
    
    
 The package tetris.player.computer corresponds
    tetris/player/computer (on Unixoid systems).
      
  
  
Imports and Nesting 
  
  
 Import statements deal with .class files, not nested packages.
    
  
  
No Really, Where are the Packages? 
  
  
 Knowing that package X  is in directory X  isn’t too helpful.
    
    
 Because where’s directory X ? 
      
  
  The classpath 
    
 It lists parent directories that may contain package directories. 
      
  
  
The -classpath Option 
  
  
 javac and java have the -classpath command-line option
  (also -cp for java) to set the classpath. 
    
    
 The default classpath is the current directory (.).
    
  javac always searches .; java only by default.
      
  
  The classpath is a colon separated list of directories.
    
    
 On Unix; check for other systems.
      
  
  
Classpath Example. 
$ ls 
A  B
$ cat A/Ca.java
package A;
public class Ca { }
$ cd B
$ cat Cb.java
class Cb { A.Ca ca; }
$  
 
  
 
Classpath Example.. 
$ javac Cb.java
Cb.java:1: package A does not exist
class Cb { A.Ca ca; }
            ^
1 error
$  
  
  
 Huh?  Why doesn’t package A exist?
    
Classpath Example... 
  
  
 Classpath defaults to .
  
  The search for packages starts in directory B.
  
  Classpath needs to point to B’s parent to find A.
    
  
  
Classpath Example.... 
$ javac -classpath .. Cb.java
$  
  
The CLASSPATH Environment 
  
  
 Typing “-classpath  blah ” all the time is a pain.
    
    
 Unless maybe if you use make or ant. 
      
  
  You can set the CLASSPATH environment variable instead.
    
    
 javac and java use the contents of CLASSPATH if
    -classpath isn’t given.
    
  Don’t forget . for java if you need it.
      
  
  
Cumulative Packages 
  
  
 A package may appear in several class-path directories.
      /usr/java: java.lang
/usr/local/java: java.lang
 
    
    
 The total package is 
the union 
    of the individual packages.
      
    
  
  
Cumulative Package Search 
  
  
 Class search is sequential through the class path until the class is
  found.
    
  
  This is a security problem.
/evil-doer/java: java.security.cert Certificate
      /usr/java: java.security.cert Certificate
 
    
  
  
Tracing Package Search 
  
  
 The -verbose:class JVM option produces output describing class
  loading. 
    
    
 It produces a lot of information. 
    
  It writes to std-out rather than std-err.
      
  
  Example
$ java -verbose:class fact
[Loaded java.lang.Object from shared objects file]
[ blah blah blah ]
[Loaded java.math.BigInteger from shared objects file]
[Loaded java.math.MutableBigInteger from shared objects file]
1! = 1
2! = 2
[ and so on ] 
  
  
Method Scope 
  
  
 Method scope is independent of class scope.
  
  By default, methods have package scope.
    
    
 Any class in the same package can access the method. 
      
  
  Methods with public scope can be accessed from any class in any
  package.
    
    
 Public-scope methods have the public modifier. 
      
  
  
Method Scope Example. 
$ cat A/Ca.java
package A;
public class Ca { 
  public void yes() { }
  void no() { }
  }
$ cat B/Cb.java
import A.Ca;
class Cb { 
  void blue() {
    Ca ca = new Ca();
    ca.yes();
    ca.no();
    }
  }
$  
Method Scope Example.. 
$ javac B/Cb.java
B/Cb.java:7: no() is not public in A.Ca; 
cannot be accessed from outside package
    ca.no();
      ^
1 error
$  
Private Method Scope 
  
  
 A method m with private scope m.
    
    
 Right now, the only sensible features are other methods.
    
  No access from other classes in the same package. 
      
  
  Private-scope methods have the private modifier.
    
Instance-Variable Scope 
  
  
 An instance variable can have public, package, or private scope.
    
    
 By default, instance variables have package scope.
      
    
  Public or private scope is indicated by the public or
    private modifier.
      
  
  Access rules are the same as for methods.
    
Class and Instance Methods 
  
  
 By default, methods are called on class instances.
classInstance .method (args ...)
 
    
    
 A method manipulates the instance’s state, among other things.
      
  
  If there’s no class instance, there’s no method.
  
  But what about constructors?  Where’s the instance there?
    
Class Methods 
  
  
 A constructor is an example of a class method 
    
 There’s no this inside a class method. 
      
  
  A method becomes a class method by using the static modifier.
static double sin(double x) { ... }
 
  
  Static and access are independent.
static public, static private
 
  
  
Class Method Access 
  
  
 Class methods are accessed using the name of the containing class:
ClassName .staticMethod (args ...)
 
    
    
 And package if necessary. 
      
  
  Static import 
import static class .staticMethod ;
import static class .*;
 
    
Class vs. Instance Methods 
  
  
 Class methods can directly access only other class methods.
    
    
 A class method can access instance methods via a class instance. 
      
  
  Instance methods can directly access class methods.
    
    
 Going through the class name is fine too.
      
  
  
Method-Access Example 
class blob {
  static void cm1() { }
  void im2() { 
    cm1(); this.cm1(); 
    }
  static void cm3() {
    cm1(); blob.cm1();
    im2(); 
    blob b = new blob();
    b.im2(); b.cm1();
    }
  } 
 
 
  
 
Java Programs 
  
  
 Java programs (as opposed to applets) start executing in the main
  method of the form
public static void 
main(String args[]) { ... }
 
  
  Beware the sticky static problem.
    
    
 The main() static spreads throughout the class.
    
  Have a main class that does nothing but set-up and run the program.
      
  
  
Example. 
  
Example.. 
$ javac -Xlint fact.java
fact.java:29: non-static method 
fact(java.math.BigInteger)
 cannot be referenced from a static context
 System.err.println(i + "! = " + fact(i));
                                      ^
1 error
$
 
Example... 
  
Class and Instance Variables 
  
  
 As with methods, so with variables.
  
  A variable becomes a class variable static
  modifier. 
static public double pi = 3.1415;
 
  
  Static and scope are independent.
    
    
 Class variables should be private or immutable.
      
  
  Class and instance methods can access class variables independent of
  scope.
    
Comments 
  
  
 Comments can either be single line or multi-line.
// Ignore to end of line.
/* 
  Ignore until next star-slash.
*/ 
    
    
 Multi-line comments do not nest.
      
  
  Javadoc comments 
/**
  blah blah blah
*/ 
  
  
Javadoc 
  
  
  
 javadoc is a JDK documentation tool.
    
    
 It extracts javadoc comments from Java source and formats them as
    HTML pages.
      
  
  
    
  
 
   
Javadoc Comments 
  
  
 Javadoc comments is text with HTML tags and @-keywords.
    
    
 javadoc parses @-keywords, passes along HTML.
    
  Be careful mixing HTML and @-keywords.
      
  
  A feature’s javadoc comment immediately precedes the feature.
  
  Javadoc can document packages, classes, methods, and variables.
    
Class Comments 
  
  
 A class comment should immediately precede the related class.
  
  Useful @-keywords for classes include @author, @version,
  and @deprecated.
    
 
 Always document a deprecated feature's replacement.    
  
  By default, only public classes are documented.
    
    
 Document them all, pick subsets with javadoc options.
      
  
  
Method Comments 
  
  
 A method comment immediately precede the related method.
  
  Useful @-keywords for methods include @param, @returns,
  and @throws.
    
    
 javadoc performs sanity checks on these keywords.
      
  
  By default, only public and protected methods are documented.
    
Field-Variable Comments 
  
  
 A field-variable comment immediately precedes the related variable.
  
  By default, only public and protected variables are documented.
  
  Example
/** The card’s rank.
    @invariant 0 ≤ rank < 13
*/
private int rank;
 
  
  
Other Comment Types 
  
  
 Javadoc also provides package and overview (framework, subsystem)
  documentation. 
  
  These comments require separate HTML files.
    
    
 package.html and overview.html 
      
  
  File placement depends on directory structure.
    
    
 package.html goes in the package directory. 
    
  overview.html goes in some ancestor directory.
      
  
  
Running Javadoc 
  
  
 javadoc’s a complicated program, but simple invocations usually
  do. 
  
  Make sure you have a separate documentation directory.
    
    
 javadoc generates a lot of files. 
    
  Use the -d command-line option, or run javadoc in the
    documentation directory.
      
  
  
Javadoc Quirks 
  
  
 javadoc is a chatty program.
    
    
 javadoc warnings are useful but hard to see.
    
  Use the -quiet command-line option to cut the chatter.
      
  
  By default, javadoc documents only public or protected features.
    
 
 Use the -private or -package command-line options to
      document more features.    
    
  
  
Javadoc Example 
  
Generalizing Javadoc 
  
  
 Doclet  generalizes javadoc.
    
 
 Create new document components and document formats.    
  
  The trick: generate documentation that’s Java code.
    
    
 Boilerplate-code generation.
    
  Used a lot in J2EE systems.
      
  
  
Summary 
  
  
 Scope sets an entity’s extent and visibility.
    
    
 public, package (default), and private. 
    
  Classes, methods, and field variables.
      
  
  Packages group related class files.
    
    
 Packages sort of map onto directories. 
    
  The class-path maps onto packages.
      
  
  Javadoc is a cumbersome swiss-army knife.