25 August 2020

Welcome to CSC 4260, Topics in Java

Download these work-saving files They will run on Python 2 or 3 (only 2 is running on the web sever). You should install Python3 on your lappy.

makePy.py

#!/usr/bin/env python
#    Author: Morrison
#    Date created: 1 September 2015
#    Program: makeC.py
#    This program produces a shell Python program with a dated comment
#    box.  Use it whenever you create a new program, and you 
#    will know WHEN  you produced things.  The default filename
#    is moo.py.
from sys import argv
from datetime import datetime
def monthNames(n):
    x = ["", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", 
    "Aug", "Sep", "Oct", "Nov", "Dec"]
    return x[n]
fileName = "moo" if (len(argv) < 2) else argv[1]
outFile = open(fileName + ".py", "w")
now = datetime.now()
nowString = "%s %s %s" % (now.day, monthNames(int(now.month)), now.year)
outFile.write("""# Author: Morrison
#  Date created: %s
#  Date last modified: %s
#  Program: %s.py
# 
""" %(nowString, nowString, fileName))

makeJava.py


#!/usr/bin/env python
from sys import argv
import sys
import os
import datetime
##################################################
#  makeJava.py
#  This program makes a skleton JavaFX file and
#  puts an author and date comment into it
#  Usage:
#     makeJava.py Program mmddyy
#         Program: program name
#         mmddyy is a date  ex: 052619 is 26 May 2019
##################################################
if len(argv) < 2:
    print("Usage: makeJava.py Program ")
    quit()
progName = argv[1]
mos = ["", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
date = datetime.date.today()
mo=date.month
day = date.day
yr = date.year
print("date=%s, month = %s, year = %s" %(day, mo, yr))
fp = open(progName + ".java", "w")
fp.write("""/**************************************************
*   Author: Morrison
*   Date created: %s %s %s
*   Date last modified: %s %s %s
**************************************************/
""" %(day, mos[mo], yr, day, mos[mo], yr))
fp.write("""
public class %s
{
    public %s()
    {
    }
    
    public static void main(String[] args)
    {
    }
}"""%(progName, progName))
fp.close()

They will save you work. If you don't have it already, make a directory named bin in your home directory. If you put these files in that directory and add it to your path, you will have access to them anywhere in your file system. They produce a shell file with a dated comment header.

When I ran makeJava.py with the comand-line argument Sample, I got this. I did this yesterday morning at 9:28A.

/**************************************************
*   Author: Morrison
*   Date created: 24 Aug 2020
*   Date last modified: 24 Aug 2020
**************************************************/

public class Sample
{
    public Sample()
    {
    }
    
    public static void main(String[] args)
    {
    }
}

You can change the Author line to your name.

Grunty Mechanics: The Edit-Compile-Run Cycle

You should all know the basic steps in Java programming

  1. Create source code in a .java file using a text editor.
  2. Compile with the javac. If your program makes syntactic sense, a .class file containing Java Bytecode will be created. If not, read the error messages, fix your code, and repeat this step.
  3. Run your code with the java command. For a file to be executable, it must have a main method with sig String[].

Style Conventions

You will adhere to these conventions. They are practices by most Java coding shops.

  1. I require that all class names be capitalized. Failing to do so annoys other programmers and causes confusion.
  2. It is a compile time error to have a file name mismatch. If your file is named Foo.java, then the public class in the file must be named Foo
  3. State and static memebers should be listed at the top of the class's body.
  4. Be consistent in curly-brace formatting. Both of these styles are OK, but be consistent. Flying brace:
    public static void main(String[] args){
        System.out.println("fooment");
    }
        
    Curly braces on their own lines: (I use this)
    public static void main(String[] args)
    {
        System.out.println("fooment");
    }
        
    An unwise consistency is "the hobgoblin of small minds." A wise consistency is a humognous virtue to have as a programmer. Consistent style makes errors easier to find and root out. It also will help you to win friends and influence people.
  5. Set your text editor to have a tab be four spaces. This can be done in the editor's preferences.
  6. Constant symbols (as opposed to just final) should be typeset in all caps. (Example: Math.PI)
  7. JVM, JDK and JRE: What are they?

    These are three important items you should know about

    JDK The Java DevelopmentKit contains all of the tools you need to create Java programmers. It contains the javac compiler.

    JRE The Java Runtime Environment contains the Java libraries and the java command that allows you to run Java programs.

    JVM This is a virtual computer (implemented in software). Its machine language is called Java bytecode When you run Java, the Java bytecode is converted into your native machine code, and run by your computer's CPU. Java bytecode is a standard; it is the same on on all computing platorms.

    This six-minute video gives more detail. It's a "required reading."

    Starting and Stopping jshell

    The jshell application is a Java REPL, much like Python's interactive shell. It runs Java statements. Here is how to start and stop it.

    (base) MAC:Tue Aug 25:10:53:T1> jshell
    |  Welcome to JShell -- Version 14.0.1
    |  For an introduction type: /help intro
    
    jshell> /exit
    |  Goodbye
    

    You are familiar with Python's REPL.

    (base) MAC:Tue Aug 25:10:55:T1> python
    Python 3.7.4 (default, Aug 13 2019, 15:17:50) 
    [Clang 4.0.1 (tags/RELEASE_401/final)] :: Anaconda, Inc. on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> 4*5
    20
    >>> x = 5
    >>> x *= 6
    >>> x
    30
    >>> quit()
    

    The Java Primitive Types

    So let's go exploring. Here are some types you remembered.

    Here we see them being created. Variables in Java are keenly aware of their type and will only store data of their type. See the error message here when you try to assign a boolean to an integer.

    (base) MAC:Tue Aug 25:10:56:T1> jshell
    |  Welcome to JShell -- Version 14.0.1
    |  For an introduction type: /help intro
    
    jshell> boolean isSane = false;
    isSane ==> false
    
    jshell> isSane
    isSane ==> false
    
    jshell> int x = 5;
    x ==> 5
    
    jshell> x = true
    |  Error:
    |  incompatible types: boolean cannot be converted to int
    |  x = true
    |      ^--^
    
    jshell> double gamma = .577;
    gamma ==> 0.577
    
    jshell> char s = 'a';
    s ==> 'a'
    

    Let us continue in the session and see an exception.

    jshell> int q = s
    q ==> 97
    

    There is fluidity between the integer and character types. This comes from Java's C heritage. The character value 'a' is stored as the number 97. This is the ASCII encoding scheme. In fact, Java uses Unicode values to store characters.

    jshell> (int) 'A'
    $7 ==> 65
    
    jshell> for(int k = 65; k < 72; k++){System.out.println((char)k);}
    A
    B
    C
    D
    E
    F
    G
    
    jshell> for(int k = 97; k < 104; k++){System.out.println((char)k);}
    a
    b
    c
    d
    e
    f
    g
    

    A cast is a temporary request to regard a variable of one type as being of another. The grammar for a cast is as follows.

    (newType) variable
    

    The expression variable can be a varible or a literal.

    Here is an illegal cast.

    jshell> (int) true
    |  Error:
    |  incompatible types: boolean cannot be converted to int
    |  (int) true
    |        ^--^
    

    Here are some more primitive types.

    An Aside on ASCII Begin by noticing this cool feature for base conversion in Java.

    jshell> Integer.toString(97, 2)
    $10 ==> "1100001"
    
    jshell> Integer.toString(65, 2)
    $11 ==> "1000001"
    
    jshell> Integer.toString(1000, 16)
    $12 ==> "3e8"
    

    You will see that the ASCII values for upper-case letters are 32 lower than their lower case brethern. This means that, to switch the case of a letter, you just flick the 32s place. This is an extremely fast low-level operation. You will see that many "counterpart characters" have ASCII values differing by a power of 2. Check out [] and ().

    One other thing of note about characters. They are actually Unicode values.

    jshell> (int) 945
    $5 ==> 945
    
    jshell> (char) 945
    $6 ==> 'α'
    
    jshell> (char) 946
    $7 ==> 'β'
    
    jshell> (char) 947
    $8 ==> 'γ'
    
    jshell> (char) 5545
    $9 ==> 'ᖩ'
    
    jshell> (char) 2833
    $10 ==> '଑'
    
    jshell> (char) 666
    $11 ==> 'ʚ'
    
    jshell> (char) 667
    $12 ==> 'ʛ'
    
    jshell> (char) 668
    $13 ==> 'ʜ'
    
    jshell> (char) 669
    $14 ==> 'ʝ'
    

    We are now going to look at the four integer types.

    public class Num
    {
        public static void main(String[] args)
        {
            byte b = 0;
            while( b >= 0)
            {
                b++;
            }
            //System.out.println(b);
            shorty();
            //testInt();
        }
        public static void shorty()
        {
            //a short is two bytes
            short b = 0;
            while( b >= 0)
            {
                b++;
            }
            System.out.println(b);
        }
        public static void testInt()
        {
            int b = 0;
            while( b >= 0)
            {
                b++;
            }
            System.out.println(b);
        }
    }
    

    Uncomment the line \texttt{System.out.println(b)} and keep the two function calls commented.

    unix> javac Num.java
    unix> java Num
    -128
    unix> 
    

    The byte type holds a one-byte integer. This is a signed type in two'c complement notation, so when you add 1 to its maximum value 127, the result is its lowest value, -128. Check this out.

    (base) MAC:Tue Aug 25:11:14:T1> jshell
    |  Welcome to JShell -- Version 14.0.1
    |  For an introduction type: /help intro
    
    jshell> byte b = 120;
    b ==> 120
    
    jshell> b++;
    $2 ==> 120
    
    jshell> b++;
    $3 ==> 121
    
    jshell> b++;
    $4 ==> 122
    
    jshell> b++;
    $5 ==> 123
    
    jshell> b++;
    $6 ==> 124
    
    jshell> b++;
    $7 ==> 125
    
    jshell> b++;
    $8 ==> 126
    
    jshell> b++;
    $9 ==> 127
    
    jshell> b++;
    $10 ==> -128
    

    picture of donuts

    Now uncomment the function call shorty() and comment out the line before it.

    unix> javac Num.java
    unix> java Num
    -32768
    unix> 
    

    A short is a 16-bit integer.

    Comment shorty() and uncomment testInt(). Here is what happens

    unix> javac Num.java
    unix> java Num
    -2147483648
    unix> 
    

    The int type is a 32 bit integer. This'd take a while with a long, but here is how you can see the maximum value for all of the integer types.

    jshell> Byte.MAX_VALUE
    $1 ==> 127
    
    jshell> Short.MAX_VALUE
    $2 ==> 32767
    
    jshell> Integer.MAX_VALUE
    $3 ==> 2147483647
    
    jshell> Long.MAX_VALUE
    $4 ==> 9223372036854775807
    

    Guess how you see the minimum value ...

    You can tell a type is primitive if it is all lower-case letters. Primitive types store their value directly. Since long is the largest primitive type (8 bytes), a Java variable never stores more than 8 bytes of memory.

    The Stack and the Heap These are two important areas of memory. The stack manages all method calls. Note that the starting method call in any Java program is the main method of the class that is being run. So, when you launch Java, main goes on the stack in a container called a stack frame or activation record. If a method gets called, a stack frame is created for its call and it goes on top of the caller's frame. When a method returns, its stack frame is popped off the stack and subsequently overwritten. This goes on until main returns, at which time, the program's execution is ended.

    Variables created inside of methods are called local variables and they only live in their stack frame. Once the stack frame is popped, the local variables inside are no longer accessible. They will quickly get overwritten.

    Now let us discuss the rest of the Java type system.

    Java Object Types

    When you invoke jshell, you can think of it as being inside of a main method. Here we create a local variable of primitive type. That variable, along with its value 5, is stored on the stack because it is a local variable to main.

    jshell> int x = 5;
    x ==> 5
    

    Now let's make a variable for a String. Notice that String is capitalized. That tells you that String is not a primitive type. Variables of type String are of object type.

    jshell> String s = "Hello";
    s ==> "Hello"
    

    Varialbes of object type have methods.

    jshell> s.charAt(0)
    $3 ==> 'H'
    
    jshell> s.substring(1,2)
    $4 ==> "e"
    
    jshell> s.substring(1,4)
    $5 ==> "ell"
    
    jshell> s.length()
    $6 ==> 5
    
    jshell> s.substring(1,5)
    $7 ==> "ello"
    

    Strings can get to be humongous. Check out this nonsense here. We just PUMPED IT UP and made a string with over 8 million characters.

    jshell> String foo = "*"
    foo ==> "*"
    
    jshell> foo = foo + foo
    foo ==> "**"
    
    jshell> foo = foo + foo
    foo ==> "****"
    
    jshell> foo = foo + foo
    foo ==> "********"
    
    jshell> foo = foo + foo
    foo ==> "****************"
    
    jshell> foo = foo + foo
    foo ==> "********************************"
    
    jshell> foo = foo + foo
    foo ==> "****************************************************************"
    
    jshell> foo = foo + foo
    foo ==> "************************************************ ... *************************"
    
    jshell> foo = foo + foo
    foo ==> "************************************************ ... *************************"
    
    jshell> foo = foo + foo
    foo ==> "************************************************ ... *************************"
    
    jshell> foo = foo + foo
    foo ==> "************************************************ ... *************************"
    
    jshell> foo = foo + foo
    foo ==> "************************************************ ... *************************"
    
    jshell> 
    
    jshell> foo = foo + foo
    foo ==> "************************************************ ... *************************"
    
    jshell> foo = foo + foo
    foo ==> "************************************************ ... *************************"
    
    jshell> foo = foo + foo
    foo ==> "************************************************ ... *************************"
    
    jshell> foo = foo + foo
    foo ==> "************************************************ ... **************************
    
    jshell> foo = foo + foo
    foo ==> "************************************************ ... **************************
    
    jshell> foo = foo + foo
    foo ==> "************************************************ ... **************************
    
    jshell> foo.length()
    $26 ==> 131072
    
    jshell> foo.length()
    $27 ==> 131072
    
    jshell> foo = foo + foo
    foo ==> "************************************************ ... **************************
    
    jshell> foo = foo + foo
    foo ==> "************************************************ ... **************************
    
    jshell> foo = foo + foo
    foo ==> "************************************************ ... **************************
    
    jshell> foo = foo + foo
    foo ==> "************************************************ ... **************************
    
    jshell> foo = foo + foo
    foo ==> "************************************************ ... **************************
    
    jshell> foo = foo + foo
    foo ==> "************************************************ ... **************************
    
    jshell> foo.length()
    $34 ==> 8388608
    

    You might ask, "How does that fit inside of a stack frame? The whole stack can only hold a few megabytes. How does this work?

    It is the magic of indirection! There is a second area of memory called the heap. The heap is a data warehouse in which every byte has its own address. The big string object is created in the heap. The only thing that foo is storing is the memory address of its string on the heap! And that is basically.... an integer. All objects you create live in the heap. Variables in the stack refer to these objects via their memory addresses.

    The English is a little eccentric but this is well worth the few minutes it takes to play. When he uses the term "reference" he is referring to the memory address of the object on the heap.

    When an object is no longer referred to it is said to be orphaned and it is subject to garbage collection. This gives a simple explanation of the process.

    How do I learn what I can do with a String? Begin by going here. Type String in the little search box. A menu will pop up; select java.lang.String You will arrive on the String Page.

    Near the top of this page you will see this.

    The String class represents character strings. All string literals in Java programs, such as "abc", are implemented as instances of this class.

    Strings are constant; their values cannot be changed after they are created. String buffers support mutable strings. Because String objects are immutable they can be shared.

    For those of you who have used Python, this is quite familar. Strings are immutible objects. Once you create them in heap memory, they cannot be changed.

    What happened here?

    jshell> String s = "Hello";
    s ==> "Hello"
    
    jshell> s = "Goodbye"
    s ==> "Goodbye"
    

    The string "Hello" is still in memory. It's just been orphaned. No varible is pointing at it so it's garbage collector bait. The variable s is just pointing at the new string "Goodbye" on the heap.

    What happened here?

    jshell> s
    s ==> "Goodbye"
    
    jshell> s += " Columbus!"
    $4 ==> "Goodbye Columbus!"
    
    jshell> s
    s ==> "Goodbye Columbus!"
    

    The string "Goodbye" is still there. A new string "Goodbye Columbus!" has been created on the heap by the string concatenation operator +, and s now points at that. We now have two orphans residing on the heap.

    Here is how to extract a character from a string. Indices work just as they do in Python or JavaScript.

    jshell> s.charAt(0)
    $6 ==> 'G'
    

    This is taboo

    jshell> s.charAt(0) = 'g'
    |  Error:
    |  unexpected type
    |    required: variable
    |    found:    value
    |  s.charAt(0) = 'g'
    |  ^---------^
    

    We found out how to produce a copy of a string that is upper-cased.

    jshell> s.toUpperCase()
    $7 ==> "GOODBYE COLUMBUS!"
    

    Assignment Start reading j1.pdf.