Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Java Stanton Vincent CSC 415: Programming Languages Dr. Lyle October 17, 2014 History of Java Development In the early 1990’s, grunge rock was in its prime and childrens’ cartoons were reaching their prime as well. In coincidence with these events is the development of a programming language called Java. James Gosling at Sun had the idea of creating a more readable, universal language than C++, so he set out to create Java. At first, the target audience for Java was consumer electronics, but quickly spread to having the title of being the Universal Programming Language, which would eventually lose momentum. (Naughton) Java is heavily influenced by C++, and has grown exponentially over the years. Countless updates have given Java more flexibility and power. To the present, 2014, Java SE 8 has been released. Previous updates have expanded the class library from a few hundred classes to over 3,000 and added many extensions such as for-each loops and lambda expressions. (Naughton) Java has expanded into one of the most powerful programming languages to ever exist and is still being developed in order to expand its capabilities and further its power. Results Java wasn’t very popular when it was released in 1991, but has gained considerable momentum through the years. The simplicity, extensibility and the minor difficulty of learning Java has gained it the status of being one of the first program languages programmers learn in their journey. In addition, the power of Java has gained it the status of being one of the most widely used programming languages of today. Java (Chan) It powers the operating system of the Playstation 3 and is used for many programming feats, some of which are very large and complicated. Java Design, Syntax and Symantics Names, Bindings, and Scopes Java offers a vast and fairly simple way for naming variables. Names in Java have no length limit, so they can be however long the user wishes. They are casesensitive, which means PEAR and pear are two different variables. In addition, Java uses keywords, like real, int, byte, new, and this. The user also has the option to use imported Java names to assist them in naming. (Arnold and Gosling) For example, private ClassName obj1 = null; private com.yourpackage.second.ClassName obj2 = null; is a basic implementation of importing Java names. (Sebesta) As for bindings in Java, static and dynamic bindings are both possible. If a variable needs to be static, the user must explicitly declare the variable as static. For example: static int i = 0; All other variables are stack-dynamic variables, unless they are objects, in which case they are explicit heap-dynamic variables. (Liang) Java only utilizes static scoped variables throughout its programming syntax. Instance variables scope the entire class definition. Parameter variables scope only the method body in which they were used. In addition, local variables scope from the point of declaration to the end of the method body. (Liang) 2 Java Data Types Java offers a wide and expansive option for data types, some of which are numeric, character string, array and list. (Java Basic Data Types) Pertaining to the primitive types, it offers integer, Boolean and character types. Byte, short, int, and long fall under the Integer subclass of the numeric type. Float and double are the only options for floating-point types. As for the Boolean types, there are, of course, only true and false. True returns a value of 1 and false returns a value of 0. The only type under the character type is char, which is used to specify a single character, rather than a string. (Liang) Continuing, the character string types allow users to create and use strings. It offers the String class and the StringBuffer class, which uses built in functions to append and manipulate strings, rather than use overloaded operators which the String class uses. Java offers the option of static length to the length of strings. (Sebesta) With the introduction of Java 5.0, enumeration types were added. To specify an enumeration type in Java, the keyword enum is used. There are some restrictions to the enumeration type in Java. The user cannot perform any arithmetic operations on enumeration types and no enumeration variable can be assigned a value outside its defined range. (Sebesta and Watt) One of the most powerful and expansive options in Java that outdoes most other programming languages is the powerful array. The following statements show how to declare, create and initialize arrays in Java: Declare: data_type[] array_name 3 Java Example: int[] fibonnaci Create: array_name = new data_type[index] Example: fibonnaci = new int[10] Initialize: data_type[] array_name = {Assign elements here} Example: int[] fibonnaci = {0,1,1,2,3,5,8,13,21,34} Java offers many types of bindings for arrays. Such are static, fixed stack-dynamic, stackdynamic, fixed heap-dynamic and the ArrayList class. In order to perform operations on arrays, the user must import the java.util.Arrays class. Such operations that can be executed on arrays are searching an array, comparing two arrays, filling an array and sorting an array. One standout feature of Java arrays that makes it stand out from most programming languages is its compatibility with multidimensional arrays. In Java, the user can have a jagged array and with as many dimensions as they desire. In addition, Java offers the slice() method to return a certain portion, or “slice”, of an array to be analyzed and manipulated. Associative arrays are also supported by standard class libraries in Java. (Sebesta and Watt) Record types are supported by different programming languages and Java is no exception. Records are defined as data classes in Java. Thus, nested records are defined as nested subclasses. Data members of such classes serve as record fields. (Sebesta) Java offers many options for the lesser defined data types, such as Tuple and List. The Tuple data type is supported by Java. As for the List data type, the classes of List and ArrayList must be utilized. These classes offer great flexibility for operations and manipulations on lists in Java. (Liang) 4 Java Type checking is another important feature of programming languages in which Java has its own set of features and characteristics like none other. Java uses coercion for type checking and it is strongly typed. This means that types can be explicitly cast, which could result in a type error. There are no implicit ways in which type errors can go undetected in strongly typed languages. As for type equivalence, object compatibility and relationship to the inheritance hierarchy are examined during type checking. Expressions and Assignment Statements In addition to the extensive amounts of data types, Java also offers a very diverse and complex amount of expressions and assignment statements. The operator evaluation order is just exactly like mathematics, Please Excuse My Dear Aunt Sally, or Parentheses Exponents Multiplication Division Addition Subtraction. The associativity of Java is from left to right. Java does offer a simplified conditional expression, which has the form of the following: Expression_1 ? Expression_2 : Expression_3 Example: I == 4 ? true: false; What the preceding statement does is determine if Expression_1 is true, then, if it is, it returns Expression_2. If Expression_1 is false, then it returns Expression_3. Java does support overloaded operators, but this topic will be discussed more extensively later. The + operator in Java can be used for addition or to concatenate strings. For example, int i = 4; System.out.print(“2 + 2 = “ + i); 5 Java Here, the + operator is used both in the message and for concatenation. Type conversions are fairly trivial in Java. For coercion in expressions, Java allows widening conversion of variables and mixed-mode expressions. In addition, it also allows explicit type conversions and even casts. However, there can be errors that arise in certain expressions. These include overflow, underflow and exceptions. Exceptions are discussed later on, but an example of this here would be division by zero. Just like C++, Java offers nearly the same kinds and amounts of relational and Boolean expressions as C++. There are the typical <, <=, >, >=, ==, and != relational expressions and || and && Boolean expressions. Short-circuit evaluation is also supported within Java. Another similarity Java has with C++ is the amount of compound assignment operators. These include +=, -=, *=, /=, %= and so on. There are also the unary assignment operators of ++ and --. (Incremental Java) Assignment as an expression is allowed in Java, but is not used frequently and only allows Boolean expressions in any conditional statement. As for multiple assignments, Java does not directly support it like Perl does, but the user can assign values to multiple variables at one time. For example, int a=b=c=5; assigns the value of 5 to a, b, and c all at the same time. Finally, mixed-mode assignments are allowed in Java, but only in a certain context. The coercion usually has to be widening in order for it to work. Only very limited narrowing conversions will work with mixed-mode assignments. Statement Level Control Structures 6 Java In addition to the vast amounts of data types and expression and assignment statements, Java also offers a vast amount of statement-level control structures. Like C++, Java uses many control expressions, multiple-selection statements and iterative statements. Like many other programming languages, Java utilizes the if…else statement. However, it does not use a then keyword like some other languages. Also, there is a switch {case; case; default;} option for a multiple-selection statement and also an if…else if…else if… option as well. As for iterative statements, the for loop is the most famous. The following is how to use a for loop correctly in Java: for(data_type var_name = value; Boolean expression; arithmetic){…} Example: for(int i = 0; i < 4; i++){…} Extending off of the for loop, there is another kind of for loop in Java, but it is known as the for-each loop. This for loop iterates per element in the variable specified. An example follows: for(data_type var_name : variable){…} Example: for(String item : itemList){…} This example iterates through all of the items in the itemList, then it exits the loop. In addition, there are while loops and do-while loops options for iterative statements as well. If the user wanted to ever exit a loop, Java comes with loop control mechanisms. The break keyword exits the loop and the continue keyword will continue the loop. All of these selection statements and iterative statements can be nested within each other. Subprograms 7 Java The subprogram capabilities of Java give it some of the greatest power any programming language has ever seen. Unlike C++, the subprogram does not need to be declared in the header of the class. There are two kinds of subprograms in Java – functions and procedures. Functions return a value, while procedures do not. The following is an example of how subprograms are written in Java: (Optional: public/private | static) return_type subprogram_name(formal parameters(if any)) {…Body} Example: double Average(int[] array){…Body…} Local variables of subprograms are stack-dynamic variables, however they can be static local variables if the user uses the keyword static. Nested subprograms are not directly supported by Java, but there are abstract ways to do so. One way is to use lambda expressions, which were introduced in Java 8. Another way is a workaround that consists of an anonymous class containing a single method. The final way is to use a named class declared as local to a method that may also be used. (Java (Software Platform)) Parameter passing methods are very important concepts to any programming language. Java offers pass-by-value, pass-by-name, which was introduced in Java 5.0, and pass-by-reference parameter passing methods. Pass-by-value parameters are scalar values only. They can be copied into stack locations and the stack then serves as storage for the formal parameters. As for the pass-by-reference parameters, they are object parameters, which can contain a scalar. At compile time, the parameters are type checked. Multidimensional arrays can be passed as parameters since they are considered objects. This gives great flexibility and power to the subprograms of Java. (Sintes) 8 Java Subprograms can be passed as parameters for other subprograms. For example: return_type <Object_Type> parameter_name; ArrayList <List> numberList; There are no pointers in Java, so users cannot call subprograms indirectly. There are overloaded subprograms in Java. They are mixed-mode expressions and most of them are constructors. To determine which subprogram to use, the types and numbers of parameters determine so. With the introduction of Java 5.0, generic subprograms were added to the arsenal of Java. They are also known as parametric polymorphisms. The following is an example of a generic subprogram in Java: public static <T> T doIt (T[] list){…} Java offers bounds as to what may be passed to these subprograms. In the preceding example, the bound is an array, since the only thing that may be passed to it is an array. Java also supports wildcard types, which can be used for any collection type of any class component. An example of this is as follows: void printCollection(Collection<?> c) {…} Closures and coroutines are not fully supported by Java. Closures can be simulated using anonymous inner class, but there is no direct way for executing closures. As for coroutines, they were modified by the Java Virtual Machine and Bytecode, and can be done abstractly through thread abstractions. (Coroutine) As for calling subprograms, Java offers a very simple method for doing just that. To call a subprogram in Java, the user simply gives the function name and its applicable parameters. For example: 9 Java double average = Average(10, 20); double Average(int i, int j) { int sum = i + j; double avg = sum/2.0; return avg; } This example passes two integers and finds the average of the two. Users may assign a subprogram value to a variable if the subprogram is a function, since functions return values. However, it is not necessary to assign the value of a function to a variable. The user can simply call the function and the function will just return the value. As for methods, the user has to just call the method. Only void functions (methods) don’t return values. For example: drawTriangle(); There is a . notation for calling subprograms. If the user wants to execute a method on a certain object, then the user specifies the name of the object and the name of the method, putting a . between the object and method name. The object type and the method return type have to match up, otherwise there will be an error. For example: triangle.drawTriangle(); As for initializing objects, the user may declare the variable, then initialize it by calling a constructor. For example: Triangle triangle = new Triangle(); 10 Java The new keyword always creates a new instance of an object and always allocates heap memory. Abstract Data Types and Encapsulation Constructs Java’s support for abstract data types is very similar to that of C++, but with a few differences. All objects are allocated from the heap and accessed through reference variables in Java. Methods must be defined completely in a class, and a method body must appear with its corresponding header, unless it is an interface. Thus, abstract data types are declared and defined in a single syntactic unit. The compiler can inline any method that is not overridden and definitions may be hidden from clients by declaring them as private. (Sebesta) Rather than having private and public classes in class definitions, access modifiers can be attached to a method and variable definitions. If an instance variable or method does not have an access modifier, it has package access. (Sebesta) One major difference from C++ is Java does not utilize destructors since it has an implicit garbage collection. In addition, as previously mentioned, Java does support parameterized abstract data types. There were some setbacks to this before Java 5.0. However, with the introduction of generic classes and subclasses in Java 5.0, these setbacks were abolished. Java offers great flexibility with passing abstract data types as parameters to subprograms. (Sebesta) As for encapsulation constructs, Java has a file structure that is similar to C#’s assembly called a Java Archive, or JAR. It is also used for deployment of Java software systems. JARs are built with the Java utility jar, rather than a compiler. (Sebesta) 11 Java Java includes a naming encapsulation construct called the package. Packages can have more than one type, class or interface, and the types in a package are partial friends of one another. Partial means that the entities defined in a type in a package that either are public or protected or have no access specifier are visible to all other types in the package. (Sebesta) Entities without access modifiers are said to have package scope, because they are visible throughout the package. Java has no need for explicit friend declarations, so it does not contain the friend functions and friend classes of C++. A package declaration must appear on the first line of the file. The following is an example of how to use the package keyword correctly: (Sebesta) package stkpkg; Users can reference the types defined in the package by using . notation. For instance: stkpkg.myStack references the type myStack in stkpkg. Of course, clients may reference types of types of types and so on. However, this can become cumbersome, so Java utilizes an import declaration, which allows shorter references and imports the entire file if specified by an asterisk. The following example imports all types of stkpkg: (Sebesta) import stkpkg.*; Support for Object-Oriented Programming Since Java is an object-oriented programming language, it has great flexibility for object-oriented programming. All Java classes must be subclasses of the root class, Object, or some class that is descendant of Object. All subclasses must have parent 12 Java classes. While Java does have a garbage collector, it may be beneficial to utilize the finalize keyword, which acts as a destructor. This may be beneficial because the garbage collector of Java does not reclaim some objects, like ones that access some resource other than the heap memory. (Sebesta) A method can be declared as final in Java, which gives it the ability that it cannot be overridden by any descendant class. When final is used with a class, it means that the class cannot be subclassed. In addition, Java offers the @Override annotation to inform the compiler to check and determine if the following method overrides a method in the ancestor class. If it does not, then the compiler issues an error. (Sebesta) Java does require the parent class constructor be called before the subclass destructor is called. The keyword super can reference the parent class, instead of the actual name of the parent class. For instance: super(9,true); If no explicit call is made, then the compiler calls the zero-parameter constructor in the parent class. Also, Java does not support private and protected derivations for classes. Single inheritance is the only kind supported by Java. However, interfaces provide partial support for multiple inheritance. An interface definition is similar to a class definition, except that it can contain only named constants and method declarations. It cannot contain constructors or nonabstract methods. It defines only the specification of a class. A class does not inherit an interface; it implements it. In fact, a class can implement as many interfaces as it wants, just as long as it implements all of the methods that appear in the interface definition. Interfaces can be used to portray multiple inheritance, by being implemented by a subclass. In addition, they offer a different kind 13 Java of polymorphism, since they are considered types. A method can specify an interface as a parameter and the method can accept any actual parameter of any class that implements it. A nonparameter variable can also be declared to be of the type of an interface. (Sebesta) Interfaces avoid some of the problems brought up by multiple inheritance, like when a class is derived from two parent classes and both define a public method with the same name and protocol. However, interfaces do not provide code reuse. One way around this is to replace one interface with an abstract class that which includes code that can be inherited. Another problem with interfaces is when a class attempts to implement two interfaces and both define methods that have the same name and protocol. As stated in the previous paragraph, Java supports abstract classes. The abstract methods of an abstract class are represented as just the method’s header. The keyword abstract must be used to define an abstract class and its methods. Abstract classes cannot be instantiated. (Liang) As for dynamic binding, all method calls are dynamically bound unless the called method has been defined as final, in which case it cannot be overridden and all bindings are static. Static binding is also used if the method is static or private, both of which disallow overriding. (Sebesta) Nested classes have several varieties in Java, all of which are hidden from all classes in their package, except the nesting class. Nonstatic classes are called inner classes and they have access to all of the members of the nesting class. Static nesting classes do not have this. The members of the inner class are accessible in the outer class. However, these references must include the variable that references the inner class object. 14 Java An instance of a nested class can only exist within an instance of its nesting class, and nesting classes can also be anonymous. A local nested class is defined in a method of its nesting class. The scope of a local nested class is always their nesting class, and a method belonging to one can access the variables defined in its nesting class and the final variables defined in the method in which the local nested class is defined. (Sebesta) Concurrency Concurrent units in Java are methods named run, whose code can be in concurrent execution with other such methods and with the main method. The process in which the run methods execute is called a thread. They are lightweight tasks, which means they all run in the same address space. The easiest way to implement and define a class with a run method is to define a subclass that inherits from its natural parent and implements the Runnable interface. Runnable provides the run method, so any class that implements Runnable must define run. An object of the class that implements Runnable is passed to the Thread constructor. Java run methods are all actors and the join method, along with shared data, allows them to communicate with each other. (Sebesta) Thread is the only class available for creating concurrent Java programs. Thread includes five constructors, and numerous methods and constants, such as run and start. All Java application programs run in threads. The yield method is a request from the running thread to surrender the processor voluntarily. The sleep method has a single parameter, which is an integer for number of milliseconds, determines how long the thread will be blocked. The join method is used to force a method to delay its execution until the run method of another thread has completed its execution. Most threads end 15 Java when they reach the end of the code, but the interrupt keyword can be used to stop a thread. (Sebesta) The priorities of all threads need not be the same in Java. The priority of a thread can be changed with the setPriority method. The priority can be obtained by using the getPriority method. Pertaining to semaphores, the java.util.concurrent.Semaphore package defines the Semaphore class, which implement counting semaphores and have the acquire and release methods. The Semaphore constructor has one parameter, which specifies the semaphore’s counter. This package also includes the deposit and fetch operations, which act as wait and release methods. (Liang)(Sebesta) Java methods can be specified to be synchronized. These methods can be considered separate threads. An unsynchronized method can act on an object anytime, but synchronized methods cannot. They are locked until they are released by the object executing them. Cooperation synchronization in Java is implemented with the wait, notify and notifyAll methods, all of which are defined in Object. notifyAll is usually used over the notify method because it awakens all of the threads on the object’s wait list by putting them in the task ready queue, rather than just a specific one. The java.util.concurrent.atomic package defines classes that allow certain nonblocking synchronized access to int, long and boolean primitive types, as well as references and arrays. The advantage of nonblocking synchronization is efficiency, because a nonblocking access that does not occur during contention will be no slower, and usually faster than a synchronized one. Nonblocking access that occurs during 16 Java contention will be faster than a synchronized one, because synchronized access will require suspension and rescheduling of threads. (Liang)(Sebesta) Java offers an alternative to the synchronized method in Java 5.0. It created an explicit locked interface named Lock. It declares lock, unlock and the tryLock methods. The predefined ReentrantLock class implements Lock. An alternative to using the intrinsic condition queue in Java is to use the Condition interface, which provides the await, signal, and signalAll methods. There can be any number of Condition objects with just one Lock object. When using signal in Condition, it can be easier to understand and more efficient since it results in fewer context switches. (Sebesta) Exception Handling and Event Handling Exceptions are quite simple in Java. The user may choose to throw an exception by using the keyword throw. In addition, the user may develop a method that displays a message of their choosing and then throw that method as an exception should something go wrong in a program. (Liang) Another facet of Java programming with respect to exception handling is the try{…body…}catch(parameter){…body…} clause. In the body of the try clause, the client puts the code that they want executed normally, while in the catch body, they put the code necessary for the exception should it occur. The exception is placed in the parameter for the catch part of the clause. Java introduces the finally clause within its syntax. Regardless if an exception is thrown or not in a try clause, some code must be executed, such as closing a file. This is where that code goes, in the finally clause. The finally clause is optional. However, if the client wanted a try-finally clause, they may do 17 Java so. A try clause with no exception handlers is perfectly legal in Java, as long as the compound statement has a throw, break, continue or return statement. (Liang) Assertions were added in Java 1.4. In order to use them, it is necessary to enable them by running the program with the enableassertions (ea) flag. The assert statement is used for defensive programming. A program may be written with many assert statements just to make sure if the correct computations are being performed. They can also be used for an aid in debugging, and can be disabled without removing them from a program. The assert keyword can be used two ways: (Sebesta) assert condition; assert condition : expression; Both continue the program if the condition is true. If the condition is false, then the first example throws the AssertionError. The second example still throws the AssertionError, except the expression is passed to the AssertionError constructor as a string and becomes a debugging output. Java comes with GUI (Graphics User Interface) components as well as Swing, which was implemented in 1998 with Java 1.2. The GUI components of Java are many and diverse. Such include JButton, JFrame, JTextField, JRadioButton, and JPanel. These allow clients to create graphic interfaces with the Java language. (Liang) Event handling is a very important concept of programming and Java, of course, provides the appropriate syntax and tools to get the job done. Java has event listeners, which execute when a certain event occurs, like a mouse clicking a certain button. Event listeners are connected to event generators through event listener registration. (Sebesta) Listener registration is done with a method of the class that implements the listener 18 Java interface. (Sebesta) The appropriate listener interface must be implemented for certain events. A failsafe way to make sure all event listener interfaces are imported is to just put import java.awt.*; at the beginning of every event listener program. In order to add an event listener to a button, text field, etc., the client must specify the name of the item receiving the event listener, then add the type of listener using . notation. For example: button1.addItemListener(this); The event handler resembles a method and is included within the code. The parameter of the event handler must be a type of event. For example: public void itemStateChanged (ItemEvent e) {…Body…}; is the proper syntax. In the body of the event handler, the client specifies what is done when that event happens. For example, when button1 is clicked, then the program stops execution. Thus, the client programs that within the event handler. The event handler is there just to show that the program supports event listening and handling. The events themselves are programmed within the event handler. (Sebesta) Other Issues While some programming languages have some issues, such as expensive compilers, Java does not really have any issues. It is a free programming language, with many free IDEs to utilize it with. There are not any known bugs in the language and the compiler is free, which usually comes with the language. Evaluation Readability The overall simplicity of Java is extremely simple. The language is definitely not difficult to read, and flows quite nicely. Java does support feature multiplicity, but all are 19 Java simplistic enough to understand by looking at them. The only operator that is overloaded in Java is the + operator. The + operator can be used for addition and for adding on variables and concatenating strings. While this may reduce readability, the overall simplicity gains bonus points. The orthogonality of Java is another facet of the language that adds to the readability. Java is extremely simple and efficient, and also allows primitive constructs to be transformed into data structures. For example, double[] arr, creates an array named arr that has double values. The data types in Java are a little expansive, but are ultimately used for certain scenarios, which programming languages should offer. This does decrease the readability, but does increase the number of tools at the clients disposal. Java offers many, many options for keywords, and this ultimately affects the readability of Java the most. The client has many options for which keywords to use where, and this will also have an effect on the writability of Java too. However, on a positive note, the form and meaning of statement design in Java is straightforward. The only setback is the use of keywords, since there are so many. Because of the vast amounts of keywords, Java’s readability is hindered in the sense that there are many keywords to learn and memorize. Writability Since Java is an extremely simple and orthogonal language, the writability of it is fairly great. Exception handling and the access of creating data structures with such ease certainly does added credibility that Java is an extremely well-writable language. The support for abstraction in Java both helps and hinders it. The readability of abstract types in Java is fairly complicated, but the writablity gains from it. Abstraction , such as trees and graphs, allows Java to handle certain events that no other programming language 20 Java may handle, but the readability is hindered from it. Thus, it is both hindered and helped from it. Expressivity is another facet of determining writability. Java offers very simple methods for expressivity and the readability of them is quite nice as well. Java offers the unary assignment operators, which increase the writability of Java. For example, it is much easier for a client to write a++;, rather than writing a = a + 1;. Not much readability is lost here either. Reliability The motto for Java when it was first brought to fruition was “Write Once, Run Anywhere”. Thus, the reliability of Java is extremely exponential in value. Java is one of the most reliable programming languages to date, because the client can write the code once and it will run anywhere in the world. In addition, the type checking at compile time is extremely desirable. This prevents the code from being run with errors in it, which some modern programming languages do not come with. These errors are detected early, which, in turn, requires less cost and time to fix them. Since Java supports vast amounts of exception handling, this adds to its reliability immensely. The ability for a program to detect a run-time error, take corrective measures, then continuing its natural programming adds great depth to reliability, and Java executes this beautifully. Finally, readability and writability also affect the reliability of a programming language. Since Java is extremely writable and very much readable, it results in being a very reliable programming language. Programs that are difficult to read are difficult to write and/or modify. Thus, Java’s readability and writability add to its reliability. 21 Java Cost The cost of Java is almost as admirable as its reliability. Java is a really cheap language to obtain, learn and implement. The cost for training people in Java is minute, in fact, it can be rounded to the cost of a textbook introducing people to Java. That is how simple and easy Java is. Writing, compiling, and executing Java code is also inexpensive, since Java is easily read, written and reliable. The compilers for Java are very reliable and quick, so hardly any cost is expended there and as to executing code. One can optimize code to shorten compile time, but this is unnecessary for small programs. Since Java is extremely reliable, the cost for it diminishes rapidly. Java does requires updates every now and then, usually within a year to two, but these updates cost nothing money-wise. The only thing that costs for the update is memory on the clients CPU, but this is hardly a concern. Portability is Java’s middle name, and slogan as well. The portability of Java gives it a much cheaper cost, and, ultimately, one of the cheapest modern programming languages. Overall The success and aspiration of Java give it its power and flexibility that already characterizes it. Java was just aimed at consumer electronics in the beginning, but now powers many complex systems and complex programs. The influx of its success drafted it as becoming the universal programming language. However, lately, this saying has lost its momentum, because certain programming languages are used for certain scenarios. Java is no different. Therefore, like the universe, Java is expanding as a language, but remains just as dense. 22 Appendix The following is a Java program that simulates a Hangman game. import java.util.Scanner; public class Assignment_9_1 { public static void main(String[] args) { char reply = 'y'; while(reply == 'y' || reply == 'Y') { String[] words = {"hitman", "final", "fantasy", "cloud", "squall", "cyan"}; String word = words[(int) (Math.random() * 6)]; StringBuilder unknown = new StringBuilder(); for(int i = 0; i < word.length(); i++) unknown.append("*"); Scanner input = new Scanner(System.in); int j = 0; while(j < 6) { if(unknown.toString().indexOf("*") == -1) break; System.out.printf("(Guess) Enter a letter in word %s > ", unknown); String in = input.next(); String guess = in.substring(0,1); if(word.indexOf(guess) == -1) { System.out.printf("\t%s is not in the word.\n", guess); j++; } else { if(unknown.indexOf(guess) >= 0) System.out.printf("\t%s is already in the word.\n", guess); else { for(int k = 0; k < word.length(); k++) if(word.substring(k, k + 1).equalsIgnoreCase(guess)) unknown.replace(k, k + 1, guess); } Appendix } } if( j == 6) System.out.println("You Lost!"); System.out.printf("The word is %s. You missed %d time(s).\n", word, j); System.out.print("Do you want to guess another word? Enter y or n > "); reply = input.next().charAt(0); } } } ii Bibliography Arnold, Ken and James Gosling. The Java Programming Language, 2nd ed. Boston: Addison-Wesley, 1998. Print. Chan, Patrick. The Java Developers Almanac. Boston: Addison-Wesley, 1998. Print. "Coroutine." Wikipedia. Wikimedia, 31 Aug. 2014. Web. 22 Sept. 2014. "Incremental Java." MoreJava. University of Maryland, n.d. Web. 22 Sept. 2014. "Java Basic Data Types." TutorialsPoint. TutorialsPoint, 2014. Web. 21 Sept. 2014. "Java (Software Platform)." Wikipedia. Wikimedia Foundation, 22 Sept. 2014. Web. 23 Sept. 2014. Liang, Y. D. Introduction to Java Programming. 9th ed. Upper Saddle River, New Jersey: Prentice Hall, 2012. Print. Naughton, Patrick. "History of Java." Java. N.p., n.d. Web. 21 Sept. 2014. Sebesta, Robert W. “Programming Languages.” 10th ed. Upper Saddle River, New Jersey: Pearson Education, Inc., 2012. Print. Sebesta, Robert, and David Watt. "Basic Data Types." EECS. Washington State University, 2004. Web. 21 Sept. 2014. Sintes, Tony. "Does Java Pass By Reference or Pass By Value?" JavaWorld. JavaWorld, 26 May 2000. Web. 21 Sept. 2014.