Refresher: Java Basics
Topics - Java Basics Notes
Knock knock… Who’s there?… … very long pause … Java! -industry joke
Editor Note:
- The material below was cobbled together for personal notes use, from attributed sources, and endured some mild look/feel massage.
 - Document Purpose: Conveniently scoped refresher on the listed Java material.
 
Sources:
- Pluralsight
 - Wikibooks
 - Photo source by Alexander Gilbertson on Unsplash
 
Runtime Environment
- Configuration
 - Security
 - Threading
 - Input/Output Variables, Data Types, and Math Operators end
 
Variables, Data Types, and Math Operators
Variables
- Name and use variables
 - Named Data Storage
 - Strongly Typed
    
int dataValue; dataValue = 100; // or int myInfo = 200; - Naming
    
- Rules allow use of letters, numbers, $ and _.
 - Convention - letters and numbers. Camel Case
 - First char not number
        
int total; int bankAccountBalance; int grade4; int level2Training; 
 - Variable Assignment
    
- Assign value to another, not reference
 - “Copy by Value”
        
int myVar = 50; int anotherVar = 100; myVar = anotherVar; System.out.println(myVar); // 100 anotherVar = 200; System.out.println(myVar); // 100end
 
 
Primitive Data Types
- Behavior
 - Most fundamental data types built into the language. Foundation of all other types used in programs.
 - 4 categories of Primitive types
    
- Integer
 - Floating Point
 - Character
 - Boolean
 
 - Integer Types
 
| Type | Size (bits) | Min Value | Max Value | Literal Format | 
|---|---|---|---|---|
| byte | 8 | -128 | 127 | 0 | 
| short | 16 | -32768 | 32767 | 0 | 
| int | 32 | -2147483648 | 2147483647 | 0 | 
| long | 64 | -9223372036854775808 | 9223372036854775807 | 0L | 
byte numberOfEnglishLetters = 26;
short feetInAMile = 5283;
int milesToSun = 92960000;
long nationalDebt = 18100000000000L;
- Floating Point Types
    
- Stores values containing a fractional portion
 - Supports positive, negative, and zero values
 - If you just put a literal, with a decimal, complier assumes double
 
 
| Type | Size (bits) | Smallest Possible Value | Largest Possible Value | Literal Format | 
|---|---|---|---|---|
| byte | 32 | 1.4x10-9 | 3.4x1038 | 0.0f | 
| short | 64 | 4.9x10-324 | 1.7x10308 | 0.0d | 
float milesInAMarathon = 26.2f
double atomWidthInMeters = 0.000000000001d; 
- Character and Boolean
    
- The char type stores a single unicode character
 - Literal values placed between single quotes
 - For Unicode code points, use \u followed by 4-digit value
 - Bool literal values are true and false
 
 
char regularU = 'U'
boolean iLoveJava = true;
Primitive Data Types are Stored by Value
- Important to understand for apps when we assign values from one variable to another
 - Each primitive type variable has its own copy of the data
 
Arithmetic Operators
- Basic operators +-/*%
 - Prefix/Postfix operators ++ –
    
int myVal = 5; System.out.println(++myVal) //6 System.out.println(myVal) //6int myVal = 5; System.out.println(myVal++) //5 System.out.println(myVal) //6 - Compound Assignment Operators +=, etc
    
- Combines an operation and assignment
 - Applies result of right side to left side
 - Stores that result in variable on left side
 
 
Operator Precedence
- Operators are evaluated in a well-defined order
    
- Postfix x++
 - Prefix ++x
 - Multiplicitive * / %
 - Additive +
 
 - Operators of equal precedence are evaluated left-to-right
 - Override with Parenthesis
 - Nested Parens from inside out
 
Type Conversion
- Implicit performed automatically by compiler
 - Widening conversion are automatic
 - Mixed Integer sides - Uses largest integer size in equation
 - Mixed Floating Point sizes, uses double (largest FP size)
 - Mixed integer and floating point, uses largest FP in equation
    
int iVal = 50; long lVal = iVal; - Explicit, performed explicitly with cast operator
 - We take responsibility for result
 - Can perform widening and narrowing
 - Floating point to integer drops fraction. Use caution with narrowing conversions.
 - Integer to floating point can lose precision
    
long lVal = 50; int iVal = (int) lVal; 
Conditional Logic, Looping, and Arrays
Conditional Logic
- Relational Operators <, <=, ==, !=, etc
 - Conditional Assignment, result = condition ? true-value : false-value;
 - Block Statement
 
int v1 = 10, v2 = 4, diff
if (v1 > v2) {
  diff = v1 -v2;
  System.out.println("v1 is bigger");
  System.out.println(diff);
}
Conditional Assignment
if-else Statement
Block Statements and Variable Scope
- A variable declared within a block is not visible outside of the block
    
- A variable’s range of visibility is known as the variable’s scope.
 
 - Variables that are in-scope, when the block starts, remain in scope.
 
Logical Operators
- Note exclusive OR XOR, false^true true^false //true
 - Conditional Logic Operators – note short-circuit eval
 
Loops
- While. Condition checked at loop start, may never execute code
 - Do-while. Condition checked at loop end. Always executes at least once.
 - For. Convenience layout compared to while. Cond checked at start.
 
Arrays
- Provide an ordered collection of elements
    
float[] theVals = new float[3]; 
For-each Loop
- Enhanced for loop
 - Handles getting collection length, accessing each value
 
for (loop-variable-declaration:array)
  statement;
Switch Stmt
- Only primitives supported are char and integer
 - Don’t forget breaks, or you’ll fall through
 - Cases and Default
 
Representing Complex Types with Classes
Classes
- OO Lang encapsulates data, operations, and usage semantics (what you want to work on and how you want to work on it)
 - Separates “what” is to be done from “how” it is done. Class implementer/author focuses on how, consumer/user focuses on what.
 - A Class is a template for creating an object.
 - Java source file name normally has same name as class.
 - A class is made up of both state and executable code
    
- Fields
        
- Store object state
 
 - Methods
        
- Executable code that manipulates state and performs operations
 
 - Constructors
        
- Executable code used during object creation to set initial state
 
 
 - Fields
        
 
Using Classes
- Use the new keyword to create a class instance (aka an object)
    
- Declare variable.  Simply allocates space to store reference to actual object we want to use.
        
Flight nycToSf; - Use new keyword, assign that the value of new flight.
 - The call to new flight allocates the memory associated with that class, returns back a reference to it.
        
nycToSf = new Flight(); - Variable nycToSf is not the object but a reference to it
 - All in one
        
Flight nycToSf = new Flight(); - Notice how created Flight object returns its reference, and is provided to reference constructor.
 
 - Declare variable.  Simply allocates space to store reference to actual object we want to use.
        
 - Classes are Reference Types
    
- Example1: Flight flight1 = new Flight();
        
- Variable flight1 holds a reference to the newly created flight object.
 
 - Example2:
        
Flight flight1 = new Flight(); Flight flight2 = new Flight(); flight2 = flight1; - In the above, the object flight1 isn’t copied over flight2. The reference variable is simply repointed.
 
 - Example1: Flight flight1 = new Flight();
        
 - So Reference Types and Primitive Types have some different behavior.
 
Encapsulation and Access Modifiers
- When using an object, a dev shouldn’t need to know a whole lot about how it is built
 - Encapsulation - hiding the internal representation of an object
 - Java uses access modifiers to achieve encapsulation
 
Modifier | Visibility | Usable on Classes | Usable on Members — | — | — | — no access mod | Only within its own package (aka package private) | Y | Y public | Everywhere | Y | Y private | Only within its own class | N* | Y
- As private applies to top level classes; private is available to nested classes
 
Applying Access Modifiers
- Note: Once a class is marked as public, the file name must reflect the class name.
 java public class Flight { ... } // Flight.java
Naming Classes
- Same rules as variable names
 - Similar to variable naming convention, except:
    
- Use only letters and numbers
 - First character is always a letter
 - Follow the style often referred to as “Pascal Case”. Start of each word, including first, is uppercase. All others lower.
 - Use simple, descriptive nouns, avoid abbreviations.
 
 
Method Basics
- Use verb or action statement
 - Exiting: Unless there is an error, control returns to the method caller
 - Returns
    
- Single value
        
- A primitive value
 - A reference to an object
 - A reference to an array (arrays are objects)
 
 - Example, see return value of a flight object
        
public Flight createNewSpecialFlightBlah(...) { ... return newFlight; 
 - Single value
        
 
Special References: this and null
- Java provides special references with predefined meanings
 - “this” is an implicit reference to the current object
    
- Useful for reducing ambiguity
 - Allows an object to pass itself as a parameter
 
 - “null” is a reference literal
    
- Represents an uncreated object
 - Can be assigned to any reference variable
 
 - Java Literals are syntactic representations of boolean, character, numeric, or string data.
    
- Literals provide a means of expressing specific values in your program.
 
 - Both static and instance members of reference type not explicitly initialized are set to null by Java
 - 0 for numeric values and false for booleans.
 - For variables declared in methods - Java requires them to be initialized
 - See Initializers below
 
Field Encapsulation, Accessors, and Mutators
- In most cases, a classes fields should not be directly accessible outside of the class. Hide implementation details.
 - Accessor/Mutator pattern (ie getters and setters)
 
Class Initializers and Constructors
Establishing Initial State
- Field initializers
 - Constructors
 - Initialization blocks
 
Field Initial State and Initializers
- A field’s initial state is established as part of object construction
 - Fields receive a 0 by default
 
| byte, int, short, long | float, double | char | bool | 
|---|---|---|---|
| 0 | 0.0 | ‘\u0000’ | false | 
- Field initializers allow you specify a field’s initial value as part of it’s declaration
 
Constructor and Adding Multiple Constructors
- Differ by signatures, overloading
 
Chaining Constructors and Constructor Visibility
- With multiple constructors, want to think about visibility
 - Call to other constructor must be on first line
 
public class Passenger {
    ...
    public Passenger() {
    }
    public Passenger(int freeBags) {
        this(freeBags > 1 ? 25.0d : 50.0d);
        this.freeBags = freeBags;
    }
    public Passenger(int freeBags, int checkedBags) {
        this(freeBags);  // chained
        this.checkedBags = checkedBags;
    }
    private Passenger(double perBagFee) {
        this.perBagFee = perBagFee;
    }
}
- Note chaining above when a something like this happens: 
java Passenger jane = new Passenger(2,3); 
Initialization Blocks
- Initialization blocks shared across all constructors
    
- Executed as if the code were placed at the start of each constructor
 
 
Initialization and Construction Order
- Field Init (1)
 - Init Block (2)
 - Constructor (3)
 
public class OverInitClass {
    private int theField = 1; //first
    {
        theField = 2; //second
    }
    public OverInitClass() {
        theField = 3;  //last, what would print in a getter call.
    }
}
A Closer look at Parameters
Parameter Immutability
- In Java, when you call a method, you pass parameters into it.  Those parameter values are actually copied down into the parameter.
    
- Passing by-value
 
 - Because a copy is actually passed down there, any changes you make arn’t visible outside of method.
 - Primitive types
    
- Passed into method, as copies.  Those copies don’t affect original variables (outer scope).
        
- Garbage collected when return/control passed back to calling object.
 
 
 - Passed into method, as copies.  Those copies don’t affect original variables (outer scope).
        
 - Classes
    
- Example:
        
Flight val1 = new Flight(10) Flight val2 = new Flight(20) swap(val1, val2) void swap(Flight i, Flight j) { Flight k = i; i = j; j = k; } - In the above, references val1/val2 are not altered
        
- New memory is allocated for reference type: i, j, k.
 - The pointers inside those reference type memory locations are swapped by the code.
 - When the method completes, and control passes back: i,j,k are garbage collected.
 
 - Note Important, changes made inside of method to members of passes class instances do stick.
 
 - Example:
        
 
Overloading
- Signature
    
- Number of params
 - Type of params
 - Name
 
 - Variable Number of params
    
- See below
 
 
public void addPassengers(Passenger[] list) {
  if(hasSeating(list.length)) {
    passengers += list.length;
    for (Passenger passenger : list)
        ...
  }
}
- Or
 
public void addPassengers(Passenger... list) {
Class Inheritance
Inheritance Basics and Typed References
- Java is an OO language and allows inherit/derive from other classes
 - extends keyword
 
Flight f = new CargoFlight();
- In the above CargoFlight extends Flight
 - In the above, you can’t use any CargoFlight specific methods, only Flight methods.
    
- Due to reference type of Flight, pointing to class instance of CargoFlight.
 
 - Why do the above pattern? (aka instead of the more normal CargoFlight cf = new CargoFlight();)
    
- This could be valuable when you have an unknown assortment of Flight instances and derived instances.
 - You don’t have to do extra work to see what each type is before calling something.
 - You can depend on Flight based stuff being available. Example:
 
 
Flight[] squadron = new Flight[5]
squadron[0] = new Flight();
squadron[1] = new CargoFlight();
...
Member Hiding and Overriding
- Fields
    
- If derived class has same field name, it can hide base class field if new’d with a base class type.
 - This can bite you if you call a base class method on a derived class instance.
        
- That base method only can see its local and class vars, so it will miss the derived classes hiding var.
 
 - See below
 
 
public class Flight {
    ...
    int seats = 150;
    ...
}
public class CargoFlight extends Flight {
    ...
    int seats = 12;
    ...
}
Flight f1 = new Flight();
// print f1.seats = 150
CargoFlight cf = new CargoFlight();
// print cf.seats = 12
// !!
Flight f2 = new CargoFlight();
// print f2.seats = 150
// Not 12, cargoflight derived class member var of name seats.
- Methods
    
- A workaround to the above, use a overriding method definition that returns the desired value.
 - Example:
 
 
public class Flight {
    ...
    int getSeats() { return 150; };
    ...
}
public class CargoFlight extends Flight {
    ...
    int getSeats() { return 12; };
    ...
}
Flight f1 = new Flight();
// print f1.getSeats() = 150
CargoFlight cf = new CargoFlight();
// print cf.getSeats() = 12
// !!
Flight f2 = new CargoFlight();
// print f2.getSeats() = 12
// Not 12, cargoflight derived class member var of name seats.
- We didn’t have to do anything special to override.  In Java, override happens automagically.
    
- Use @override annotation to be explicit and intentional.
 
 - You can do something special if you don’t want it overridden.
 
Object Class
- Root of Java class hierarchy
 - Every class has characteristics of the Object class
 - Useful for declaring variables, fields, and parameters that can reference any class or array instance
 - Defines a number of methods that are inherited by all objects
 - Every class inherits directly or indirectly from object class
 - Examples:
 
Object[] stuff = new Object[3]
stuff[0] = new Flight();
stuff[1] = new Passenger(0, 2);
stuff[2] = new CargoFlight();
Object o = new Passenger();
o = new Flight[5];
o = new CargoFlight();
- Won’t work
    
o.addPackage(1.0,2.5,3.0) //Nope - Options
 
CargoFlight cf = o; //Compiler Nope
CargoFlight cf = (CargoFlight) o; //Yes.  Make sure it will actually be a CargoFlight everytime.
cf.addPackage(1.0,2.5,3.0) //Yes
- “Make sure it will actually be a CargoFlight everytime”
    
if(o instanceof CargoFlight) { ... } - Popular object class methods
    
- clone - Create a new object instance that duplicates the current instance
 - hashCode - Get a hash code for the current instance
 - getClass - Return type information for the current instance
 - toString - Return string of characters representing the current instance.
 
 
Equality
- Careful
 - Example below.  f1/f2 point to two separate instances of flight class.
    
- == operator only true if with reference types if both pointing to the same object.
        
- Reference comparisons are very inexpensive
 
 - equals method from Object (base) class. Need to override to use your business logic/problem space.
 
 - == operator only true if with reference types if both pointing to the same object.
        
 
Flight f1 = new Flight(175)
Flight f2 = new Flight(175)
if(f1==f2) { //False.  Reference equals test.  Do these references both point to exact same instance?
    ...
if(f1.equals(f2)) { //False.  Using equals method from Object class, so doing same reference test above.
    ...
- Override equals method
 
class Flight {
    ...
    private int flightNumber;
    private int flightClass;
    
    @Override
    public boolean equals(Object o) {
        ... //check instanceof Flight
        Flight other = (Flight) o;
        return
            flightNumber == other.flightNumber &&
            flightClass == other.flightClass;
    }
- Now this is true
    
if(f1.equals(f2)) 
Special Reference: Super
- Similar to this, super is an implicit reference to the current object
    
- super treats the object as if it is an instance of its base class
 - Useful for accessing base class members that have been overridden
 
 
Using Final and Abstract
- By default, all classes can be extended
 - Derived classes have the option to use or override inherited methods
    
- A class can change these defaults
 
 - Use final to prevent overriding
 
public final class Passenger { //No extending/derived classes on this
    ...
- More commonly, we do want to allow derived classes, we just want to control overriding certain methods
    
- Mark method definition as final
 
 - Conversely, abstract keyword requires inheriting and/or overriding
    
- Mark method as abstract and don’t provide a body, just end with a semicolon.
 
 
Inheritance and Constructors
- Constructors are not inherited
 - A derived class must always call one of the base class constructors
 - As you define the derived class’s constructor, it will call back to the base class
    
- If you don’t provide one, the no-arg constructor on the base class will be called by default
 
 - You can explicitly call a base class constructor using super followed by parameter list
    
- Must be first line in constructor
 
 - Chaining is fine
 
More About Data Types
String Class
- The String class stores a sequence of Unicode characters
 - Stored using UTF-16 encoding
 - Literals are enclosed in double quotes
 - String objects are immutable.  If you are doing alot of string work, will be inefficient with memory.
    
- Each time you edit the string (ie add a space), a new memory allocation occurs for the entire new string
        
- And the string reference type is repointed to the new string class instance
 
 - Use a string builder
 
 - Each time you edit the string (ie add a space), a new memory allocation occurs for the entire new string
        
 - Equality
    
- Two strings with same characters fail reference check ==
 - Equals method for string class would work, does a character by character comparison.
 
 - Intern method to allow reference check to work
 
String Representation of Non-String Values
- String.valueOf provides overrides to handle most types
 - Conversions often happen implicitly
 - Class conversions controlled by the class’ toString method
    
- If you drop a class reference into a string, you’ll get the string representation of the class.
        
- com.mydomain.foo.Flight@761337
 
 - Override to create more solution adapted output for class description.
 
 - If you drop a class reference into a string, you’ll get the string representation of the class.
        
 
StringBuilder Class
- For optimal performance, set to a large value initially, growing buffer is not cheap.
    
StringBuilder sb = new StringBuilder(40) Flight myFlight = new Flight(175); String value = "strongbad"; sb.append(value) sb.append("great") sb.insert(11, "is " String message = sb.toString(); 
Primitive Wrapper Classes and Type Conversions
- Classes vs Primitives
    
- Classes provide convenience
        
- Common interaction through Object class
 - Fields and methods specific to the type
 - Con: Incurs an overhead cost
 
 - Primitives provide efficiency
        
- Can’t be treated as Object
 - Can’t expose fields or methods
 - Pro: Lightweight
 
 
 - Classes provide convenience
        
 - Primitive wrapper classes
    
- Capabilities and overhead of classes
 - Hold primitive values, interact with primitive values
 - All wrapper classes are immutable
 
 - Object
    
- Boolean
 - Character
 - Number
        
- Byte
 - Short
 - Integer
 - Long
 - Float
 - Double
 
 
 - Conversions between wrapper class and primitive
 - Most common operations are automatic
    
Integer a = 100; int b = a; Integer c = b; - Wrapper classes provide methods for explicit conversions
 - Primitive to wrapper - valueOf “Boxing”, 
Integer d = Integer.valueOf(100) - Wrapper to Primitive xxxValue, “Unboxing”, 
int e = d.intValue(); - String to primitive parsexxx
 - Note
 
String s = "87.44"; 
double s1 = Double.parseDouble(s);  //you are getting back a primitive type
double s2 = Double.valueOf(s); //returns back a reference to a wrapper class that has that value inside of it.
Using Primitive Wrapper Classes
- Take advantage of capabilities that all classes have, while working with primitive types
 - We can now treat the primitive type as an object
    
Object[] stuff = new Object[1] stuff[0] = 100; - In the above, Java will go head and get a reference to an instance of the integer wrapper class
    
- with a value of 100
 - and assign that reference into stuff[0]
 
 - Get utility of null references (code can check for null against prim wrapper class value, vs just raw primitive)
 
| Class | Select Members | 
|---|---|
| Byte, Short Integer, Long | MIN_VALUE, MAX_VALUE, bitCount, toBinaryString | 
| Float, Double | MIN_VALUE, MAX_VALUE, isInfinite, isNaN | 
| Character | TRUE, FALSE | 
Wrapper Class Equality
- Certain boxing conversions will always return same reference (for the same value)
 - Grid below: Boxing conversions that always return the same wrapper class instance
 
| Primitive Type | Values | 
|---|---|
| int | -128 to 127 | 
| short | -128 to 127 | 
| byte | -128 to 127 | 
| char | ‘\u0000’ to ‘\u00ff’ | 
| boolean | true, false | 
Final Fields and Enumeration Types
- Fields we don’t allow to be set, once they are initialized
    
- Simple final field must be set during creation of an object instance
        
- Field initializer, initialization block, or constructor
 
 - Adding a static modifier makes a final field a named constant.
        
- Cant’ be set by object instance, value is tied to class itself
 - Convention is all caps (used for magic numbers)
 
 
 - Simple final field must be set during creation of an object instance
        
 - Enumeration types
    
- Useful for defining a type with a finite list of valid values
 - Declare with enum keyword
 - Provide a comma-separated value list
 
 
public enum FlightCrewJob {
    Pilot,
    CoPilot,
    FlightAttendant,
    AirMarshall
}
public class CrewMember {
    private FlightCrewJob;
    ...
    public CrewMember(FlightCrewJob job) {
        this.job = job;
    }
}
CrewMember judy = new CrewMember(FlightCrewJob.CoPilot);
Judy.setJob(FlightCrewJob.Pilot);
Exceptions and Error Handling
Error Handling with Exceptions
Handling Exceptions by Type
- Throwable class inherits from Object
 - Error Class (handled in JVM)
 - Exception class
    
- Runtime Exception - errors that occur in your program
 - Runtime inheritance is consider non-checked exceptions
 
 - Checked exceptions
 - Compiler requires you to handle
 
Exceptions and Methods
- Exceptions propagate up the call stack, to a catch marker
    
- Can cross method boundaries
 - Exceptions are part of a methods contract
 - Method is responsible for any checked exceptions that might occur
        
- Catch the exception
 - Document that the exception might occur (use the throws clause)
 
 
 - Method overriding
    
- The throws clause of an overriding method must be compatible with the throws clause of the overridden method
        
- Can exclude exception (is already handled in base class)
 - Can have the same exception
 - Can have a derived exception
 
 
 - The throws clause of an overriding method must be compatible with the throws clause of the overridden method
        
 
Throwing Exceptions and Custom Exceptions
- Your code can throw exceptions (use throw keyword)
 - Must create exception instance before throwing (provide meaningful detail)
 - Most exception classes provide a constructor that accepts a String message or other detail
 - When caused by another exception, include originating exception
    
- All exception classes support initClause method
 - Many provide a constructor that accepts the originating exception
 
 - Custom exception types
    
- In many cases better to use existing exception type
 - Normally inherit directly from Exception class (makes them checked)
 - Constructors are often their only members
        
- Most required functionality is inherited
 - Have constructor that access required detail
 - Have constructor that accepts required detail and originating exception
 
 
 
Working with Packages
What is a Package
- Create a namespace
 - Provide an access boundary
 - Act as a unit of distribution
 - Package declaration must appear before any type declarations
 - Applies to all types within that source file
 
Packages Create a Namespace
- Type name is qualified by the package name
 
Determining a Types’s Package
- Explicitly qualifying a type would be cumbersome
 - Types in java.lang package do not need to be qualified
 - Use type imports (import keyword). Import is just a mapping for the complier.
 - Single type import or import on demand with *
    
- Single type is preferred, modern IDEs will add automatically
 
 
Packages Provide Access Boundaries
- Packages can serve as an access boundary
    
- Often referred to as package private
 - Useful for creating types and features to support functionality provided by package
        
- Types and features are not meant to be used standalone
 
 - Can apply to a type
        
- Entire type is accessible outside of the package
 
 - Can apply to type members
        
- Specific members of an otherwise accessible type are inaccessible outside of the package
 
 
 
| Modifier | Visbility | Usable on types | Usable on Members | 
|---|---|---|---|
| no access modifier | Only within its own package (aka package private) | Y | Y | 
| public | Everywhere | Y | Y | 
| private | Only within its own class | N | Y | 
| protected | Only within its own class and subclasses | N* | Y | 
- As applies to top-level classes; can be applied to nested-classes
 
Packages Act as a Unit of Distribution
- Packages provide a predictable software structure
    
- Simplifies distribution
 
 - Class files organized in hierarchical folders reflecting the package name
    
- Each part of the package name is in a separate folder
 
 - Archive files (jar)
    
- Optionally includes a manifest (can identify startup class)
 - Can be compressed
 
 
Creating Abstract Relationships with Interfaces
Introducing Interfaces and Implementing an Interface
- In java, an interface is a type that defines a contract
 - Contrast to Classes, Interfaces don’t provide an implementation
 - Classes implement interfaces - Express that the class conforms to the contract
 - Interfaces don’t limit other aspects of he class’ implementation
 
public class Passenger implements Comparable {
    ...
    public int compareTo(Object o) {
    ...
}
Implementing a Generic Interface
- Some Interfaces require additional type information, a concept known as generics
 - Example
 
public class Flight implements Comparable<Flight> {
    ...
public interface Comparable<T> {
    int compareTo(T o);
-Get rid of casts
Implementing Multiple Interfaces
- Classes are free to implement multiple interfaces
 
public class flight
    implements Comparable<Flight>, Iterable<Person> {
    ...
Declaring an Interface
- Supports a subset of features available to classes
 - Methods
    
- Name, parameters, and return type
 - Implicitly public
 
 - Constants
    
- Typed and named values
 - Implicitly public, final, static
 
 - Extending interfaces
    
- An interface can extend another interface
 - Implementing extended interface implies implementation of base
 
 
Static Members, Nested Types, and Anonymous Classes
Static Members
- Class variable. Static members are shared class wide, not individual instance.
 - Field
 - Method
    
- Performs an action not tied to a specific instance
 - Can access static fields only
 
 
Static Initialization Blocks
- Static initialization blocks perform one-time type initialization
 - Executed before type’s first use
 - Statements enclosed in brackets outside of any method of constructor
    
- Precede with static keyword
 - Can’t access instance members
 - Must handle all checked exceptions
 
 
Nested Types
- A nested type is a type declared within another type
 - Classes can be declared within classes and interfaces
 - Interfaces can be declared within classes and interfaces
 - Nested members are members of the enclosing type
    
- Private members of the enclosing type are visible to the nested type
 
 - Nested types support all member access modifiers
    
- public, package private, protected, private
 
 - Structure and scoping
    
- No relationship between instances of nested and enclosing type
 - Static classes nested between classes
 - All classes nested within interfaces
 - all nested interfaces
 
 
Inner Classes
- Each instance of the nested class is associated with an instance of the enclosing class
 - Non-static classes nested within classes
 
Anonymous Classes
- Anonymous classes are declared as part of their creation
 - Useful for simple interface implementations or class extensions
 - An. classes are inner classes
    
- An. instnce is associated with the containing class instance
 
 - Create as if you are constructing an instance of the interface or base class
 - Place opening and closing brackets after the interface of base class
 - Place implementation code within the brackets