Basics

Java does not support "free" functions (all functions and data must be encapsulated inside a class). This includes the function main() - it must be "hosted" by one, and only one, class in the application. The BasicsDemos class here is serving as that "repository". The code below must appear in a file called "BasicsDemo.java". This convention allows Java to perform "compile and link" functionality with considerably less overhead.

main() is the entry point for Java applications. It must be preceeded with the modifiers public static void. public means the function is accessible outside the class. static allows the function to be invoked without an instance of the class having been previously created. And void specifies that the function returns nothing. main() must accept a single argument of type "array of Strings". If the "signature" for main() is not exactly as specified below, the compile step works fine, but the application will fail at run-time because a main() with the proper signature was not found.

   class BasicsDemos {         // standard out
      public static void main( String[] args ) {
         System.out.println( "hello world" );
   }  }
   
   // D:\Java> doskey
   // D:\Java> setpath
   // D:\Java> javac BasicsDemos.java
   // D:\Java> java  BasicsDemos
   // hello world
The function print() sends its argument to standard-out. The function println() does the same with a carriage return appended to the end. The "plus sign" may be used to perform to concatenation.
   class BasicsDemos {         // '+' concatenation
      public static void main( String[] args ) {
         System.out.print( 1 + "st " + "print" );
         System.out.println( ", " + 2.3 + "nd " + "print" );
   }  }
   
   // 1st print, 2.3nd print
There are three kinds of comments. "//" designates a comment that is closed by the next end-of-line. "/*" opens a comment that can span multiple lines, and "**" closes the comment. "/**" specifies a documenting (or javadoc) comment.
   /** line before class */
   
   public class BasicsDemos {
      /** line before value */
      private int value;
      /** line before attr */
      public int attr;
   
      /**
      line before foo()
      second line
      third line
      fourth line
      */
      public void foo( int i ) { }
   
      /** line before bar() */
      public static int bar( double d ) { return 3; }
   
      /** line before main() */
      public static void main( String[] args ) { }
   }
   
   // D:\Java> javadoc BasicsDemos.java 
   // ///// produces BasicsDemos.html \\\\\


Class BasicsDemos

   java.lang.Object
     |
     +--BasicsDemos
   

public class BasicsDemos
extends java.lang.Object

line before class


Field Summary
 int attr
          line before attr
 
Constructor Summary
BasicsDemos()
           
 
Method Summary
static int bar(double d)
          line before bar()
 void foo(int i)
          line before foo() second line third line fourth line
static void main(java.lang.String[] args)
          line before main()
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

attr

   public int attr
line before attr
Constructor Detail

BasicsDemos

   public BasicsDemos()
Method Detail

foo

   public void foo(int i)
line before foo() second line third line fourth line

bar

   public static int bar(double d)
line before bar()

main

   public static void main(java.lang.String[] args)
line before main()


Flow of Control

if, else, else if, for, and while work just like C. By default, a single statement is expected to follow each construct.
   class BasicsDemos {         // if then else
      public static void main( String[] args ) {
         if (5 < 4)
            System.out.println( "less than" );
         else if (5 == 4)
            System.out.println( "equal" );
         else
            System.out.println( "greater than" );
   }  }
   
   // greater than
Instead of a single statement, a block of statements may be designated with curly braces.
   class BasicsDemos {         // block of statements
      public static void main( String[] args ) {
         if (5 < 4) {
            System.out.print( "less " );
            System.out.println( "than" );
         } else if (5 == 4)
            System.out.println( "equal" );
         else {
            System.out.print( "greater " );
            System.out.println( "than" );
   }  }  }
   
   // greater than
An else statement always "binds" to the closest if. Below, the indentation is lying to the reader about its correct flow of control.
   class BasicsDemos {         // else goes with the closest if
      public static void main( String[] args ) {
         if (3 <= 4)
            if (3 == 4)
               System.out.println( "equal" );
         else
            System.out.println( "greater than" );
   }  }
   
   // greater than
If you want the else statement to associate itself with the first if statement, then the second if statement must be enclosed in its own level of scope (it must go inside of curly braces).
   class BasicsDemos {         // using {}'s to designate if-else association
      public static void main( String[] args ) {
         if (3 <= 4) {
            System.out.println( "less than or equal" );
            if (3 == 4)
               System.out.println( "equal" );
         } else
            System.out.println( "greater than" );
   }  }
   
   // less than or equal
A while loop continues to iterate until its conditional expression returns false.
   class BasicsDemos {         // while loop
      public static void main( String[] args ) {
         int i = 1;
         while (i < 10) {
            System.out.println( "i is " + i );
            i = i + 1;
   }  }  }
   
   // i is 1
   // i is 2
   // i is 3
   // i is 4
   // i is 5
   // i is 6
   // i is 7
   // i is 8
   // i is 9
The body of the while loop can be collapsed to a single statement by using the side-effecting post-increment operator.
   class BasicsDemos {         // while loop
      public static void main( String[] args ) {
         int i = 1;
         while (i < 10)
            System.out.println( "i is " + i++ );
   }  }
A comparable for loop is more succinct. It includes 3 components: initial-statement, conditional-expression, and iteration-statement.
   class BasicsDemos {         // for loop
      public static void main( String[] args ) {
         for (int i=1; i < 10; i++)
            System.out.println( "i is " + i );
   }  }
Any or all 3 components of a for loop may be blank. continue causes the current iteration of a loop to be abandoned. break causes the entire loop to be abandoned.
   class BasicsDemos {         // for loop, break
      public static void main( String[] args ) {
         int i=1;
         for ( ; ; ) {
            if (i > 10)       break;
            if (i % 2 == 1) { i++;  continue; }
            System.out.print( i++ + " " );
   }  }  }
   
   // 2 4 6 8 10
The "ternary" operator allows an entire if/then/else block to be written as an expression and embedded in a larger statement. The entire expression below must be enclosed in parentheses, or else the larger concatenation expression gets confused.
   class BasicsDemos {         // ternary operator
      public static void main( String[] args ) {
         if (5 < 4) System.out.println( "less than" );
         else       System.out.println( "greater than" );
         System.out.println( ((5 < 4) ? "less" : "greater") + " than" );
   }  }
   
   // greater than
   // greater than
   
   ////////////////////////////// lab - WhileLoop \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
   ////////////////////////////// lab - ForLoops \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
   ////////////////////////////// lab - Factorial_for \\\\\\\\\\\\\\\\\\\\\\\\\\\\\
   ////////////////////////////// lab - Factorial_while \\\\\\\\\\\\\\\\\\\\\\\\\\\

Data types and expressions

Java's primitive data types (and their platform-independent sizes) are There are four integral types in Java: byte, short, int, and long. An octal literal is indicated with a leading zero, and a hexidecimal literal with a leading "0x". An integral literal is of type int unless explicitly followed by the letter 'L' (for long).

float and double literals include a decimal point, or an exponent part (an "E??"), or a trailing F/f (float) or D/d (double). Literals with a decimal point are assumed to be of type double unless explicitly cast otherwise.

boolean variables may only be assigned the values true and false (0 and 1 are not legal values).

A char represents a Unicode character using a 16-bit unsigned number. A char literal must be enclosed in single quotes: 'a', '\t', '\u????' (a Unicode code is specified with exactly 4 hex digits).

   class BasicsDemos {         // primitive data types
      public static void main( String[] args ) {
         int     in = 0x41;
         double  du = 4.2e1;
         boolean bo = false;
         char    ch = '\u0041';
         System.out.println( "--" + in + "--" + du + "--" + bo + "--" + ch + "--");
   }  }
   
   // --65--4.2--false--A--
Expressions in Java are mostly identical to C. Note the use of the equality and assignment operators below. Conditional expressions must return a boolean value. if (i < 10) and while (true) are legal. if (i) and if ((boolean)i) are not.
   class BasicsDemos {         // expressions
      public static void main( String[] args ) {
         char    ch = 'A';
         boolean bo = false;
         int     flag = 1;
         System.out.println( "ch is " + ch + ", +32 is " + (char)(ch+32) );
         System.out.println( "! bo is "  + ! bo );
         System.out.println( "bo == is " + (bo == false) );
         System.out.println( "bo = is "  + (bo = true) );
         // if (flag) System.out.println( "flag is true" )   // compile error
         if (flag == 1) System.out.println( "flag is true" )
         if (bo) System.out.println( "bo is true" )
   }  }
   
   // ch is A, +32 is a
   // ! bo is true
   // bo == is true
   // bo = is true
   // flag is true
   // bo is true
Java supports variables of two different scopes Member variables are implicitly initialized to zero, or to "zero like" values (false or null) whenever an instance of the type is created. These member variables can be explicitly initialized on the same line as their declaration. The initialization will occur right before the class constructor is called (for non-static variables), or, at class load-time (for static variables).

Automatic variables are not implicitly initialized. They must be explicitly initialized before being used. The compiler studies the code to determine if each variable is definitely initialized before its first use. If the compiler cannot determine this, then a compile-time error occurs.

When an array is "constructed" (see the next section), its elements are automatically initialized.

   class BasicsDemos {         // initialization
      public static int memberVariable;
      public static void main( String[] args ) {
         // int localVariable;
         // System.out.println( "localVariable is "  + localVariable );
         // BasicsDemos.java:151: localVariable may not have been initialized.
         int localVariable = 99;
         System.out.println( "memberVariable is " + memberVariable );
         System.out.println( "localVariable is "  + localVariable );
   }  }
   
   // memberVariable is 0
   // localVariable is 99
Java implements arrays as first-class objects. The "array" class has a public attribute named length. This attribute is equal to the number of elements in the array. Subscripting starts at zero. The "array" class hides all pointer arithmetic. It raises an exception if an attempt is made to use a subscript value that is out of bounds.

To create and use an array, you must account for three steps.

  1. Declaration
  2. Construction
  3. Initialization
Declaration tells the compiler what the array's name is, and what the type of its elements will be (e.g. int[] list, or, double[][] twoDee). The square brackets can come before or after the array name (e.g. int[] list, or, int list[]). The declaration does not include the size of the array. Size is specified at construction.

Note: the style "int[] list" is preferred, because the variable "list" is not an int, it is an array of int. Keeping the "type" information together improves readability.
Construction occurs when the array is created with the new operator. At construction, the elements of the array are automatically initialized to zero (for numeric types) or values similar to zero (for non-numeric types). Initialization can be performed with curly braces (similar to C++), or by assignment within a loop.
   class BasicsDemos           // arrays
      public static void main( String[] args ) {
         // step 1
         int[] list1;     // recommended syntax
         // int list1[];  // alternate legal syntax
         // step 2
         list1 = new int[3];
         // demo of default initialization
         //    (arrays are objects and "know" their own length)
         for (int i=0; i < list1.length; i++)
            System.out.print( list1[i] + " " );
         System.out.println();
         // step 3
         for (int i=0; i < list1.length; i++)
            list1[i] = i + 1;
         for (int i=0; i < list1.length; i++)
            System.out.print( list1[i] + " " );
         System.out.println();
   
         // steps 1 and 2
         int[] list2 = new int[3];
         // step 3
         for (int i=0; i < list2.length; i++)
            list2[i] = list2.length - i;
         for (int i=0; i < list2.length; i++)
            System.out.print( list2[i] + " " );
         System.out.println();
   
         // steps 1, 2, and 3
         int[] list3 = { 2, 4, 6 };
         for (int i=0; i < list3.length; i++)
            System.out.print( list3[i] + " " );
         System.out.println();
   }  }
   
   // 0 0 0
   // 1 2 3
   // 3 2 1
   // 2 4 6
   
   ////////////////////////////// lab - RandomArray \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
String is not a primitive data type, it is a class in Java's standard library. But, it has been enhanced by the Java architects to the point that it feels very much like a primitive data type. The first line demonstrates that Strings can be created and initialized as easily as primitive types. The second line is the syntax for creating a normal object.

While Java does not support overloading of operators for user-defined data types, the third line demonstrates that class String allows concatenation to be invoked by use of the '+' operator. Strings also interact intelligently with Java's "output operator" [System.out.println()]. With its unique initialization, concatenation, and output capability, it stands alone among classes. The String class will be covered more in a later section.

   class BasicsDemos {         // String
      public static void main( String[] args ) {
         String one = "abc";
         String two = new String( "def" );
         String thr = one + two;
         System.out.println( "one is " + one );
         System.out.println( "the length of " + thr + " is " + thr.length() );
   }  }
   
   // one is abc
   // the length of abcdef is 6

Receiving input

Input can be communicated from the user to the application's main() by supplying "command line arguments". Whatever is typed after java BasicsDemos will be packaged as an array of Strings and passed to main() as its single parameter. DOS will cause all characters within double quotes to be treated as a single argument. Unlike C++, args[0] is the first command line argument.
   class BasicsDemos {         // command line input
      public static void main( String[] args ) {
         for (int i=0; i < args.length; i++)
            System.out.println( args[i] );
   }  }
   
   // D:\Java> java BasicsDemos first 234 "here i am" 4.56
   // first
   // 234
   // here i am
   // 4.56
   
   ////////////////////////////// lab - ArgsInput \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
The most basic example of prompting for and receiving keyboard input is:
   import java.io.*;
   
   class BasicsDemos {         // low level keyboard input
      public static void main( String[] args ) {
         byte[] buf = new byte[60];
         int    num = 0;
         System.out.print( "Enter a string: " );
         try {
            num = System.in.read( buf );
         } catch (IOException ex) {
            System.out.println( ex );
         }
         String str = new String(buf).substring( 0, num-2 );
         System.out.println( "--" + str + "--" );
   }  }
   
   // Enter a string: here i am
   // --here i am--
A "higher level" approach (but equally complex - for an entirely different set of reasons) is:
   import java.io.*;
   
   class BasicsDemos {         // higher level keyboard input
      public static void main( String[] args ) {
         BufferedReader rdr =
            new BufferedReader( new InputStreamReader( System.in ));
         String str = null;
         System.out.print( "Enter a string: " );
         try {
            str = rdr.readLine();
         } catch (IOException ex) {
            System.out.println( ex );
         }
         System.out.println( "--" + str + "--" );
   }  }
   
   // Enter a string: here i am
   // --here i am--
There ought to be a better way !     The answer is - "roll your own". Create your own user-defined data type that encapsulates the "useful fiction" (the abstraction) of keyboard input. The file "Read.java" has been supplied for this purpose. Notice that "class methods" are being used. Since "everything in Java is an object", it is not possible to define a normal "stand-alone" function. But, by declaring a function to be a "class method", the same functionality can be produced. To call each function, simply concatenate the name of the class, the "dot" operator, and the name of the class method.
   class BasicsDemos {         // "roll your own" keyboard input
      public static void main( String[] args ) {
         System.out.print( "Enter a char: " );
         System.out.println( "  " + Read.aChar() );
         System.out.print( "Enter an int: " );
         System.out.println( "  " + Read.anInt() * 2 );
         System.out.print( "Enter a double: " );
         System.out.println( "  " + Read.aDouble() * 2. );
         System.out.print( "Enter an string: " );
         System.out.println( "  -" + Read.aString() + "-" );
         System.out.print( "Enter two ints: " );
         for (int i=0; i < 2; i++)
            System.out.print( "  " + Read.cinInt() );
         System.out.println();
   }  }
   
   // Enter a char: dog
   //   d
   // Enter an int: 42
   //   84
   // Enter a double: 4.2
   //   8.4
   // Enter an string: the quick brown fox
   //   -the quick brown fox-
   // Enter two ints: 123 234
   //   123  234
   
   // Enter an int: -24
   //   -48
   // Enter a double: 1.2 3.4
   // java.lang.NumberFormatException: 1.2 3.4
   //   0.0
   // Enter two ints: -111, -222
   //   -111  -222
   
   // Enter an int: 4.2
   // java.lang.NumberFormatException: 4.2
   //   0
   // Enter a double: 4e2
   //   800.0
   // Enter two ints: 12  1.2
   //   12java.lang.NumberFormatException: 1.2
   //         at java.lang.Integer.parseInt(Integer.java:346)
   //         at java.lang.Integer.parseInt(Integer.java:384)
   //         at Read.cinInt(Read.java:34)
   //         at ReadDemo.main(ReadDemo.java:13)
   
   ////////////////////////////// lab - KeyboardInput \\\\\\\\\\\\\\\\\\\\\\\\\\\\\
To convert between int and String, use class methods that have been defined in the class Integer. Note: if the extra parentheses are not used in the first println() statement, then both integers are converted back into Strings and string concatenation is performed.
   class BasicsDemos {         // String <==> int conversions
      public static void main( String[] args ) {
         int    num = Integer.parseInt( args[0] );
         String str = Integer.toString( num );
         System.out.println( "int twice is " + (num + num) );
         System.out.println( "string twice is " + str + str );
   }  }
   
   // C:> java BasicsDemos 23
   // int twice is 46
   // string twice is 2323
   
   ////////////////////////////// lab - parseInt() \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

Functions

Since "everything in Java is an object", it is not possible to define normal "stand-alone" functions. But, by declaring a function to be a "class method", it is possible to achieve the same effect. A class method is specified by use of the keyword static. The "signature" of the function consists of: its name, its return type, and the number and type of its arguments.
   class BasicsDemos {         // function with pass by value
      public static int square( int in ) {
         return in * in;
      }
      public static void main( String[] args ) {
         System.out.println( square( Integer.parseInt(args[0]) ) );
   }  }
   
   // C:> java BasicsDemos 9
   // 81
Here is a function that needs to return two values, so two "out" arguments have been specified. Unfortunately, it is not working.
   class BasicsDemos {         // function with pass by value
      public static void decompose( int in, int tens, int ones ) {
         tens = in / 10;
         ones = in % 10;
      }
      public static void main( String[] args ) {
         int tens=0, ones=0;
         decompose( Integer.parseInt(args[0]), tens, ones );
         System.out.println( "tens is " + tens + ", ones is " + ones );
   }  }
   
   // C:> java BasicsDemos 42
   // tens is 0, ones is 0
"There is only ONE parameter passing mode in Java - pass by value." [James Gosling]   BUT - passing an object reference by value behaves like pass by reference. Since arrays are objects, we can specify a single array argument, and the extra level of indirection provided by the object reference can give us what we want.
   class BasicsDemos {         // function with "pass by reference"
      public static void decompose( int in, int[] pieces ) {
         pieces[0] = in / 10;
         pieces[1] = in % 10;
      }
      public static void main( String[] args ) {
         int[] tensOnes = new int[2];
         decompose( Integer.parseInt(args[0]), tensOnes );
         System.out.println( "tens is " +tensOnes[0] + ", ones is " +tensOnes[1] );
   }  }
   
   // C:> java BasicsDemos 42
   // tens is 4, ones is 2
   
   ////////////////////////////// lab - Fahrenheit \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
   ////////////////////////////// lab - Factorial_recursion \\\\\\\\\\\\\\\\\\\\\\\
   ////////////////////////////// lab - GCD \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
Function overloading allows the same name to be used for multiple functions. The functions must differ in their argument lists; differing only in their return value is not sufficient. Java does not support C++ default arguments, but function overloading can provide a similar capability.
   class BasicsDemos {         // function overloading
      public static void foo() {
         foo( 1, 2 );
      }
      // public static int foo() {
      //    return 42;
      // }
      // Error: methods can't be redefined with a different return type
      public static int foo( int a ) {
         foo( a, 2 );
         return 42;
      }
      public static void foo( int a, int b ) {
         System.out.println( "a is " + a + ", b is " + b );
      }
      public static void main( String[] args ) {
         foo();
         foo( 11 );
         foo( 11, 22 );
   }  }
   
   // a is 1, b is 2
   // a is 11, b is 2
   // a is 11, b is 22