Getting Started




Intro



Java is a "high level" programming language, which means that it is easy to understand by humans. It is also an "OOP" language, or object oriented programming language, which means that it is modeled after the real world: you can make objects which have properties and behaviors, much like real world objects. These two things make Java a very good first programming language to learn before you jump into all of the other languages that are out there. Read on to learn about where, why, and how to write Java code.

Note: This course doesn't require any actual programming - if you just read it you will be able to learn it - however doing actual programming will help it stick in your mind much better.


One reason that Java is so powerful is because it is very flexible. I could write Java code on my windows computer, and you could run it on your Linux desktop, and share it with your friend who has a Mac OS apple computer, and it would run exactly the same way on all three. In other programming languages, you may have to write a different version of a program for each operating system, because they may process data differently. However, you can write only one version of a program in Java and the JVM, or Java Virtual Machine (a program that comes with Java when you download it) will translate the Java program into code that the specific computer that the JVM is on can read. This process is known as compiling. As you can imagine, this makes it very easy to write applications that can run on many devices. Sun Microsystems, the original creator of Java, marketed it as “write once, run anywhere”.


Setting Up



Technically, you can write Java code inside any text editor, like notepad, github, docs, word, etc., but because you want to be able to compile and run your code to test it, an IDE is a better option. IDE is an acronym for Integrated Development Environment. It is a program that, at its most basic, lets you write, compile, and run code. A good IDE for beginners is Dr. Java. It is a single .jar file which is lightweight, easy to download, and there is no setup or installation. You can download it here. I find the jar file version easier to use, but the Windows App is fine if you prefer that version. It offers the basic functions but is simple enough to not give beginners information overload. Later in this course, we will transfer over to using Eclipse, a more advanced Java IDE, but because it is very complex, we will start out with using Dr. Java.

Setting up line numbers is strongly recommended. In Dr. Java, go to Edit > Preferences > Display Options > Show All Line Numbers

A number of examples will be shown during this course. If you are coding along, it is advisable to make a new file for each program you make instead of replacing the content of a single file for each example. This way you have plenty of material to reference later on when you are coding your own projects. When you save your program in Dr. Java, you will get three files. They will all have the same name but different file type extensions. One will be .java, one will be .java~, and one will be .class. The .java one is the one you can edit, while the .class one can be run from the command console, and has binary code. Make sure that when you open a file to edit, compile, or run it in Dr. Java, you use the .java one.


The Big Picture




Classes and Objects



As mentioned before, Java is object oriented. This means that you can create objects with properties, which in Java are called states, fields, or instance variables. These objects also have behaviors, which are called methods or functions. We first create a ‘blueprint’ or ‘recipe’ for an object, and then create as many objects as we want with this blueprint. For example, we could make a bicycle ‘blueprint’ (which is called a class, short for classification) which has properties, like the number of gears, height of seat, and manufacturer name, and behaviors, like increasing/decreasing the cadence, raising/lowering the seat, and changing gears. This file, called a class definition file, would hold all of the information on what a bicycle is in a program. Below is an example of a class definition file. You probably won’t understand most of it, but just see if you can see where the properties and behaviors are.


Comments



Anything on a line after two forward slashes is a comment. Comments are notes in the code that indicate what it does, to make maintenance and further developing easier. The text inside of a /* and */ is also a comment, which can span multiple lines. In Dr. Java, comments are in green font, so the text in green in the examples is not actual code but an explanation of what it does.


Methods



In Java, the behaviors of an object are called methods, and are essentially functions. Java methods can have multiple or zero inputs, but only zero or one outputs. A methods’ inputs are called parameters, while the output is called the output, or return value.

Methods can be parameterized or non-parameterized, which means that they have or don’t have parameters, respectively. Methods can also be void or non-void, which means that they don’t return or do return some value, respectively. Therefore, we can make the following table to show all of the possible types of methods.

Void Non-Void
Parameterized Void and Parameterized Non-Void and Parameterized
Non-Parameterized Void and Non-Parameterized Non-Void and Non-Parameterized

Take a look at the bicycle class from before: changeSeatHeight(int change) and changeGear(int gear) are parameterized, while speedUp() and slowDown() are not. All four methods are void, because they don't return a value but rather do something in the program, such as adjusting the bicycle's instance variables.


Beginning Concepts




Main Method



So far, we have learned that in Java you can define objects with properties and behaviors, also known as states and methods. These make up a ‘blueprint’ of an object, called a class definition file. However, even if we have all of the blueprints in the world, if we don’t have construction equipment we can’t use any of them. So, we are now going to look at executable code, where we can make and manipulate objects and other things. This is going to be in its own special method, called the main method, and for now we are going to make it in its own class (file). It has a special method declaration, (the line holding the modifiers, return type (we’ll learn more about this later: it’s the void part), name, and parameters) and it looks like this:

Don’t worry if you don’t know what all of the keywords mean, as long as you can recognize the class and main method declarations you are doing great!


General Flow



Every Java program starts with a main() method, which either just runs through, or creates objects. It could also call (use/activate/start) functions/methods not related to objects, but we’ll get to that later. If it creates objects or runs other methods, it will run the code in those methods, which might call other methods, etc. This progression may be dependent on external conditions like user input. Then, like the game Minecraft, the program will remain responsive to input until it is ended or it will close itself after outputting something or finishing running.


Before we move on we have to define two terms that will be necessary to understand later on: runtime vs compiletime. Runtime is the time during which the program is running, while compiletime is the time during which the program is compiling.


Statements



In Java, most of the code that we write is in statements or blocks. Statements are generally a single line of code, which ends with a semicolon, that contains a single instruction for the computer. A code block generally consists of either a declaration or condition, followed by opening and closing curly braces ( '{' and '}' ), which contain statements or other code blocks. For example, a class is a code block, because it contains the class declaration, followed by curly braces with other code blocks inside it. When compiling code to be run, the JVM reads one statement or block at a time starting with the first line of the main method.


Variables



As programmers, one of the most fundamental things we have to do is manipulate data, be it numbers, letters, true/false values, etc. When doing this, however, we may not know in advance (before compiletime) what these values will be. This is where variables come in. Variables are like containers for data, and depending on what type of data we want them to hold we can make them in different "sizes". These "sizes" are called types, and there are two types of types: primitive and reference types. For now, we are only going to deal with primitive types, but we will learn about reference types pretty soon.


When creating a variable, we must declare it and then initialize it. We can declare a variable by stating its type and its name. There are eight primitive types: byte, short, char, int, float, long, double, and boolean, which hold different types of data. Byte, short, int, and long can hold integers of different sizes, char can hold single charaters, float and double can hold decimal values, while boolean holds a true/false value. Here's an example of declaring each of the eight types:

Initializing a variable simply means setting its value for the first time. We do this using the assignment operator, which assigns the operand or expression on the right side to the variable on the left side:

We can even declare and initialize a variable in the same exact statement, like so:


The Console



As of yet, we are not advanced enough to make our own popup window to output data. However, using something called the console, we can still output data so that we can see the values of expressions without having to look into our source code. The console is generally located at the bottom of the IDE:

One way to print to the console is with the System.out.print(); command:

I have dragged the console up so you can see the output and the code. Notice two things: whatever you want to print goes inside the parenthesis in the System.out.print() statement, and when printing strings of characters they need to be enclosed in double quotes. You may also notice that the two “Hello World”s are right next to each other. This may be what we want, but we also may want to have a line return after each print statement. This can be achieved with the System.out.println(); command:

As you can see, the computer put a line drop after the first and second println statements. What is happening with the System.out.print(); command (henceforth referred to as a SOP command), is that the class System (which comes with Java) has an instance variable called out, which is an object with methods called print() and println(). Knowing all of this isn’t necessary right now, just knowing how to write a SOP statement and what it does is the important part.


In the above section, we learned how to use a method, or function: the SOP statement, which can print to the console. Earlier, we learned that methods have parameters, which are the inputs of a function. When we call a function, or use it in our program, we have to pass it values inside the parenthesis. These are called arguments. The difference between arguments and parameters is that parameters are the data that a function receives, while arguments are the data that a program sends to a function. Note that if we have a method accepting one int parameter, I cannot send it double parameters. The type of the argument has to match the type of the parameters.


Terms and Conventions




Operators



In Java, there are many operators, which are functions that are built into the Java language. All of the operators work on two operands, aside from the unary operators, which work on a single operand. They can be classified into several groups: arithmetic, relational, logical, assignment, unary, and bitwise/bitshift. Below are descriptions and examples of all of them.


Arithmetic



Addition (+):
Both operands are added together.

Subtraction (-):
The operand on the right side is subtracted from the one on the left side.

Multiplication (*):
The two operands are multiplied together.

Division (/):
The operand on the left side is divided by the operand on the right side. Examples of addition, subtraction, multiplication, and division:

Modulus (%):
The modulus operator is related to division: it gives the remainder of a division operation. It is signified by the % operator (not to be mistaken for percent). The left operand is divided by the right operand, and the answer is the remainder. Some examples:


Relational



Sometimes in Java we may want to determine the relative sizes of two values. In this case, we would need to use relational operators. There are five of them.


Greater than (>):
Evaluates to true if the left operand is greater than the right one. Otherwise evaluates to false.

Less than (<):
Evaluates to true if the left operand is lesser than the right one. Otherwise evaluates to false.

Equal to (==):
Evaluates to true if the operands are equal. Otherwise evaluates to false.

Greater than or equal to (>=):
Evaluates to true if the left operand is greater than or equal to the right operand. Otherwise is false.

Less than or equal to (<=):
Evaluates to true if the left operand is lesser than or equal to the right operand. Otherwise is false.


Logical



The relationships between quantities in single expressions are not the only relationships that we might need to evaluate. Sometimes, we want to evaluate the results of two different expressions. To do this, we need logical operators. There are two of them.


Logical OR (||):
Evaluates to true if left expression or right expression or both are true. If neither are true, evaluates to false.

Logical AND (&&):
Evaluates to true if both left and right expressions are true, but false if only one or neither are true.


Unary



In Java, there are several operators that operate on only one operand. These are called unary operators.


Unary minus (-):
Negates an expression, effectively reversing its sign.

Logical Complement (!):
Also known as a NOT operator, it inverts the value of a boolean. It can also be used in expressions involving relational or logical operators surrounded in parenthesis.

Increment (++):
Increments the value of a variable by one. When placed before a variable it is increased immediately, however when it is placed after a variable the statement is evaluated first and then the variable is increased before moving onto the next statement.

Decrement (--): Decrements the value of a variable by one. When placed before a variable it is decreased immediately, however when it is placed after a variable the statement is evaluated first and then the variable is decreased before moving onto the next statement.


Binary




Intro to Binary



In normal life, humans generally use the base 10 number system. We have 10 symbols which we put into a place value system to symbolize all types of numbers. However, computers run using binary (base 2), which only has two digits: 1 and 0. To understand how this works, we need to understand how base 10 works, and then extend this to other bases.

Everyone knows what the 1s place, 10s place, 100s place etc. are, however not everyone knows why the places are those numbers. The 1s place is really the 100s place, the 10s is 101s, 100 is 102, etc., and .1 is 10-1, .01 is 10-2, and .001 is 10-3, etc. For example, 10345 represents the integer 10,345 = 1·104 + 0·103 + 3·102 + 4·101 + 5·100. Therefore, instead of calling the 1s place the 1s place and the 10s place the 10s place, we should call the 1s place the 0th place, the 10s place the 1st place, the 100s place the 2nd place, etc., essentially referring to a given place as the power the base is raised to. This allows us to define the nth place as the bns place, where b is the base.

Using this system in binary, the 0th place is the 1s place (20 = 1), the 1st place is the 2s place (21 = 2), the 2nd place is the 4s place (22 = 4), etc., and the -1st place is the 1/2s place (2-1 = ½), the -2nd place is the 1/4ths place (2-2 = ¼), and the -3rd place is the 1/8ths place (2-3 = ⅛), etc.

We can now write binary numbers! The number 10 in base 10 (1010) is 1010 in base 2 (10102), because 10102 = 1·23 + 0·22 + 1·21 + 0·20 = 8 + 0 + 2 + 0 = 1010. Another example: 11000112 = 1·26 + 1·25 + 0·24 + 0·23 + 0·22 + 1·21 + 1·20 = 64 + 32 + 0 + 0 + 0 + 2 + 1 = 9910. To practice this concept, try converting all of the following binary numbers to base 10 and base 10 numbers to binary.


A) 112
B) 11012
C) 101102
D) 1011012
E) 1710
F) 910
G) 3510
H) 11710




Two's Complement



Technically, the bitwise complement is an operator, but we need to discuss it before learning about two's complement, which we need before the other operators.


Bitwise Complement (~):
This operator, when put before a binary number, inverts every 1 to a 0 and every 0 to a 1. Keep in mind that depending on the range of your variable (in bits), you may have up to 64 zeros before your number. For example, the number one as an int (in binary) is 00000000 00000000 00000000 00000001. This means that if you flip it, it is 11111111 11111111 11111111 11111111 11111111 11111110. Note that the bitwise complement of x (denoted by ~x) equals negative x, minus 1 ( (-x) - 1 ). Now, we will learn why this is so.


At some point during this section, you may have asked a pretty important question: Where do negative numbers come in? You may also have asked why a byte, with eight digits, can only hold half of what it should be able to hold. 111111112 is 25610, but bytes can only hold up to 127. The answer is that the other half of values are the negative numbers, which are calculated using something called two's complement. In two's complement, the base 10 numbers 0 to 127 are represented by the binary numbers 0 to 127, while the base 10 numbers -128 to -1 are represented by the binary numbers 128 to 255. The same follows with bigger data types. The first half of possible values are positive while the second half are negative. The following image might clear this up if it’s confusing.

To get the negative version of a number, subtract one and complement (invert) all of the digits. To get the positive version of a negative number, do the same thing: subtract one and complement all of the digits.

Here is a two’s complement calculator that you can mess around with.

Note: If you are interested in how computers store information, check out this resource, which explains many things that are interesting yet out of the scope of this course.


Binary Operators



Aside from the normal arithmetic and relational operators, there are a few special operators used for binary numbers. These fall into two categories: Logical and Bitshift.


Logical Operators (Bitwise Complement was covered above):

Bitwise OR (|):
Compares two binary numbers, and place by place does an OR comparison of the values, which means that the nth place of the new binary number is a 1 if either number has a 1 at the nth place, and a 0 if neither number has a 1 at the nth place. Also known as inclusive or.

Bitwise AND (&):
Compares two binary numbers, and place by place does an AND comparison of the values, which means that the nth place of the new binary number is a 1 if both numbers have a 1 at the nth place, and a 0 if only one or neither of the numbers have a 1 in the nth place.

Bitwise XOR (^):
Compares two binary numbers, and place by place does a XOR comparison of the values, which means that the nth place of the new binary number is a 1 if only one number has a 1 at the nth place, but a 0 if both or neither of the numbers have a 1 at the nth place. Also known as exclusive or.

Bitshift Operators move the 1s and 0s of a binary number to the left or right. There are two types of bitshift operators: signed and unsigned. They all take two operands, the left being a starting value (which is operated on in binary form) and the right being the amount of places to shift the digits of the starting value.

Signed Right Shift (>>):
This operator shifts the digits of the binary representation of the left operand to the right the right operand times. If the first operand is 5 (00000101 in binary), and the second is 2, the result is 5 >> 2 = 00000010. The leftmost digits are filled with whatever the leftmost digit was in the original number. The number 10000000 (-128 using two’s complement) shifted right 3 is 11110000, because the original number had a one in the leftmost place. This effectively preserves the sign, because a 0 in the leftmost digit is a positive number while a 1 there is a negative number.

Unsigned Right Shift (>>>):
Does the same thing as the signed right shift (>>), but always fills the left digits with 0s, regardless of what the original digit in the leftmost place was. The number 10101010 >>> 2 is 00101010, while 10101010 >> 2 is 11101010. The first one doesn’t preserve the sign and fills 0s regardless of the original number. The second one preserves the sign and fills 0s or 1s based on the original right operand.

Left Shift (<<):
Operates similar to the unsigned right shift (>>>), because it moves all of the digits of the left operand to the left the right operand times, filling in 0s on the right. For example, 10110011 << 3 equals 10011000.


Assignment




Casting




Intermediate Concepts




Conditionals




If Statements




Switch Statements




Loops




While Loops




For Loops




Methods




String Methods




Math Methods




Writing Methods




Common Algorithms




Data Structures




Arrays




ArrayLists




HashMaps




OOP Concepts




Inheritance




Interfaces




Polymorphism




Quick Recap




Classes and Objects




Methods




Statements




Data Structures




Polymorphism




Keywords




Programming in Action




Using Scanner




In Strings




In the Console




In Text Files




Using Writer




Javax Swing




JFrame




JTextField and JTextArea




JButton




Advanced Concepts




Nested Classes




Static Nested Classes




Inner Classes




Local Classes




Anonymous Classes




Lambda Expressions




Annotations




Generics