Control statmements are used to determine the flow of execution in a program. In the previous sections, the code was executed line by line, in the order it was written. By using control statements, we are able to create programs that take different paths depending on the state of the application. Let's look at an example:
System.out.print("Enter your age: ");
Scanner scanner = new Scanner(System.in);
int age = scanner.nextInt();
if (age < 13) {
System.out.println("You are young");
}
else if (age < 20) {
System.out.println("You are a teenager");
}
else if (age <= 50) {
System.out.println("You are middle aged");
}
else {
System.out.println("You are old");
}
scanner.close();
In the example above, only one of the four statements will be printed to the screen ("You are young", "You are a teenager", "You are middle aged", "You are old"). The program is not run line by line, and three of println statements won't be run at all. By using control statements, we're able to create dynamic programs that do different things in different situations. There are three types of control statements: selection statements, iteration statements, and jump statements. Let's start with selection statements, and we'll cover iteration and jump statements in the next sections.
Selection statements are used to determine which statement(s) are run at a certain time. The two types of selection statements in Java are if statements and switch statmenets. You saw an example of if statements in the last example. Here is the general form of if statements:
if (boolean condition)
{
//some action
}
else
{
//some other action
}
If the boolean condition evaluates to true, the code inside of the if statement is executed, otherwise the code inside of the else statement is executed. Another common way of using selection statements is by using a series of else if statements:
if (condition1) {
//action1
}
else if (condition2) {
//action2
}
else if (condition3) {
//action3
}
else {
//action4
}
In this case, only 1 of the 4 actions will be executed. The if statements are evaluated from top to bottom. If condition1 is true, then action1 is taken and the other actions are skipped. Otherwise, condition2 is evaluated, and action2 be run if condition2 evaluates to true, and the other actions are skipped. The same logic applies to condition3. Finally, if condition1, condition2, and condition3 all evaluate to false, then action4 is taken. One thing to watch out for is that only the first condition should be an if statement, the rest should be else if or else statements. Take a look at this example:
int age = 10;
if (age < 13) {
System.out.println("You are young");
}
if (age < 20) {
System.out.println("You are a teenager");
}
if (age <= 50) {
System.out.println("You are middle aged");
}
else {
System.out.println("You are old");
}
Here is the output of the program:
You are young
You are a teenager
You are middle aged
Since 10 is less than 13, 20, and 50, all of the if statements evaluate to true and are executed. There may be a few cases where you want this behavior, but most of the time this is an indicator of a bug in the code.
An alternative to using a bunch of if and else if statements is using a switch statement. The switch statement is used to evaluate a bunch of cases in order, and execute the first case that evaluates to true. Let's look at an example using if statements and see how it can be converted to a switch statement:
System.out.println("Java game menu");
System.out.println("1: new game");
System.out.println("2: continue");
System.out.println("3: high scores");
System.out.println("4: options");
System.out.println("5: quit);
System.out.print("Enter menu option: ");
Scanner scanner = new Scanner(System.in);
int option = scanner.nextInt();
if (option == 1) {
System.out.println("Starting new game");
}
else if (option == 2) {
System.out.println("Continuing game");
}
else if (option == 3) {
System.out.println("High score list...");
}
else if (option == 4) {
System.out.println("Options menu...");
}
else if (option == 5) {
System.exit(0); //this terminates the program
}
else {
System.out.println("Invalid option, please try again");
//retry logic
}
This is an example of a simple text-based menu for a java game. Although it works fine, having lots of else if statements in the code can make it a bit harder to follow. Using a switch statement can simplify the menu:
System.out.println("Java game menu");
System.out.println("1: new game");
System.out.println("2: continue");
System.out.println("3: high scores");
System.out.println("4: options");
System.out.println("5: quit);
System.out.print("Enter menu option: ");
Scanner scanner = new Scanner(System.in);
int option = scanner.nextInt();
switch (option) {
case 1:
System.out.println("Starting new game");
break;
case 2:
System.out.println("Continuing game");
break;
case 3:
System.out.println("High score list...");
break;
case 4:
System.out.println("Options menu...");
break;
case 5:
System.exit(0);
//no need to break here, program has already exited
default:
System.out.println("Invalid option, please try again");
//retry logic
}
This code is equivalent to the if statements used above, but is easier to follow. One thing to watch out for is remembering to put break; at the end of each case. This is a keyword that causes all of the other cases to be skipped. Otherwise, the default behavior is to automatically run the rest of the cases below. For example, if the break; statements were removed, you'd see this output for menu option 2:
Continuing Game
High score list...
Options menu...
You wouldn't run into this issue when using if statements. If the menu option is 2, it cannot be 3, 4, or 5, so those println statements wouldn't be executed. Nevertheless, switch statements are a good option when there's a lot of conditions to be evaluated.
Switch statements support byte, short, char, and int data types. It also supports enums and Strings, which we haven't used a lot yet but will be covered in later sections. One big limitation of switch statements is that they can only test for equality, whereas if statements can use any boolean condition. For example, in the age example earlier, we printed out "you are young" if the age is less than 13. If we used a switch, we'd have to write out all values from 0 to 12. For this reason, if statements tend to be a lot more flexible than switch statements, and are used a majority of the time in practice.
One other thing to know about if statements and switch statements is that they can be nested inside of each other. Here is an example with if statements:
int seinfeldSeasonNumber = 1;
int seinfeldEpisodeNumber = 5;
if (seinfeldSeasonNumber == 1) {
System.out.println("First season of Seinfeld");
if (seinfeldEpisodeNumber == 1) {
System.out.println("First ever episode of Seinfeld");
} else if (seinfeldEpisodeNumber == 5) {
System.out.println("Last episode of the first season of Seinfeld");
}
} else if (seinfeldSeasonNumber <= 8) {
System.out.println("One of the middle seasons");
} else if (seinfeldSeasonNumber == 9) {
System.out.println("Last season of Seinfeld");
} else {
System.out.println("Invalid season");
}
Running this program produces the following output:
First season of Seinfeld
Last episode of the first season of Seinfeld
In this example, we first check the season number of Seinfeld. If it's 1, then we know it's the first season. We then check the episode number to see if it's the first or last episode of the first season. We could add additional checks for middle episodes in the first season if needed. But the takeaway here is that nesting if statements is useful when we need to divide things into categories and subcategories. You can also nest switch statements in the same way as the if statement example. But remember that switch statements are more limited because they can only check for equality, and I've haven't come across a real-world example where nested switch statements was needed.
Let's end this section by looking at the circle area example we saw at the end of the last section:
import java.util.Scanner;
public class ExpressionsTest {
public static void main(String[] args) {
System.out.println("This program computes the area of a circle given the radius.");
System.out.print("Enter the radius of the circle in centimeters: ");
Scanner scanner = new Scanner(System.in);
double circleRadius = scanner.nextDouble();
double circleArea = circleRadius * 2 * Math.PI;
System.out.println("The area of the circle is " + circleArea + " centimeters");
scanner.close();
}
}
I'd like to add an enhancement to this program to print "Small circle" if the area of the circle is less than 10 square centimeters, "Medium circle" if the area is greater than or equal to 10 square centimeters but less than 50, and "Large circle" for anything greater than or equal to 50 square centimeters. Also, print out "Invalid area" if the user entered a negative value for the circle radius. Go ahead and give this a try on your own. I think that by writing code on your own for small projects is one of the best ways to learn a new programming language. Once you feel that you have something that works, you can check out my solution below.
So, were you successful? Here's my approach to solving this problem:
import java.util.Scanner;
public class ConditionalsTest {
public static void main(String[] args) {
System.out.println("This program computes the area of a circle given the radius.");
System.out.print("Enter the radius of the circle in centimeters: ");
Scanner scanner = new Scanner(System.in);
double circleRadius = scanner.nextDouble();
double circleArea = circleRadius * 2 * Math.PI;
System.out.println("The area of the circle is " + circleArea + " centimeters");
if (circleArea < 0) {
System.out.println("Invalid area");
} else if (circleArea < 10) {
System.out.println("Small circle");
} else if (circleArea < 50) {
System.out.println("Medium circle");
} else {
System.out.println("Large circle");
}
scanner.close();
}
}
There are a few things worth noting in this example. First, I had to use an if statement instead of switch, because the circleArea is a double, and switch does not support double. The reason for this is simple, double is a decimal value so it could be almost anything. And since switch only matches on equality, it would be pointless to use that. For example, checking if a value is 1.4 wouldn't work if I also wanted to accept 1.41 or 1.40000001. Second, I first checked if the circleArea was less than 0 and printed out "Invalid area" in that case. You could also check if circleRadius is less than 0, since they will always have the same sign. Third, I used a series of else if statements after the first if to make sure that only one of the four lines was printed ("Invalid area", "Small circle", "Medium circle", "Large circle"). I also changed the name of the class from ExpressionsTest to ConditionalsTest to reflect that we're now focusing on conditional statements. It's always a good practice to rename classes or variables as the meaning of the code changes over time.
That covers everything we need to know about conditionals for now. We'll move onto iteration statements, which give a very powerful way to repeatedly take actions until a certain condition is met.
Java Trails
Monday, October 9, 2017
Sunday, August 6, 2017
Operators and Expressions
Expressions form the basis of what we do in Java. While it is good to understand how variables and literals work, we cannot do very much with them on their own. By combining variables and literals with operators, we can create powerful expressions to perform more advanced computations. An expression can be thought of as a series of variables, literals, and operators that return a single value. Here are some examples:
3 //simple literal expression that results in a value of 3
3 + 4 //arithmetic expression resulting in a value of 7
(3 + 4) * 2 //more advanced arithmetic expression using order of operation, resulting in a value of 14
6 & 5 //bitwise expression resulting in a value of 4
3 >= 4 //relational expression resulting in a value of false
8 > 10 ? 15 < 20 ? 50 : 80 : 3 >= 2 ? 4 : 8; //very complicated expression using the ternary operator, resulting in a value of 4. Not recommended to use complicated expressions because it is difficult to read/modify
Sometimes people refer to expressions in java as operations. An operation in Java is similar to a mathematical operation - it modifies a value (or multiple values) to produce a new value. An operand is the variable or literal that is used in the operation. An operator is a symbol that is applied to the operand(s). This is best explained in an example:
int daysInAYear = 365;
int daysInThreeYears = daysInAYear * 3;
int daysInFiveYears = daysInThreeYears + daysInAYear * 2;
daysInAYear++; //leap year calculation
System.out.println(daysInAYear); //366
The first line is a simple assignment operation that takes the literal value 365 and copies it to the variable daysInAYear, which is of type integer. In this case, 365 is the operand, the = is the assignment operator that copies the value over, and daysInAYear is the result of the assignment operation (365).
The second line should be fairly straightforward. It takes daysInAYear and multiplies it by 3 to produce a new value daysInThreeYears. The variable daysInAYear and the literal 3 are the operands, and the * and = are the operators. What's interesting here is that the multiplication operator * takes two operands (daysInAYear and 3) while the assignment operator = only takes one (the result of daysInAYear * 3 = 1095). In Java, some operators take two operands and some only take one. Additionally, there is a ternary operator which takes 3 operands. This will be discussed later when we get to control statements.
The third line takes daysInThreeYears and 2 times daysInAYear to derive a new value which is assigned to daysInFiveYears. There are three operators +, *, and =. Similar to mathematics, the order in which these operators are applied is important. If daysInThreeYears + daysInAYear were calculated first, and then multiplied by 2, then the value returned would be the number of days in eight years (4 * 2). But the multiplication * operator has precedence over the + operator, so daysInAYear is first multiplied by 2 and then the result is added to daysInThreeYears, which results in the number of days in five years. Finally, the end result is assigned to the variable daysInFiveYears.
To recap, multiplication (*) has precedence over addition (+), which has precedence over assignment (=). This becomes more important as the calculations get more complex. Java provides parenthesis () to increase the precedence of the operation inside of it. For example, (daysInThreeYears + daysInAYear) * 2 would result in 8 * 365 = 2920, since the + is evaluated first, and then that result (4 * 365) is multiplied by 2. And daysInThreeYears + (daysInAYear * 2) would produce 5 * 365 = 1825, which is the same as the original expression daysInThreeYears + daysInAYear * 2. In this case, the parenthesis are unnecessary since * already has precedence over +. However, it is a good practice to include parenthesis in cases where other programmers might have a hard time figuring out what the order is. It's probably not needed in this simple example, but as operations get more complex, it really helps to see visually which parts of the operation are evaluated first. It's also a good idea to avoid overly complicated expressions and break them up in to multiple lines if needed. For example:
int daysInTwoYears = daysInAYear * 2;
int daysInFiveYears = daysInTwoYears + daysInThreeYears; //No confusion here, it's just a simple additon statement
In line 4, we come across a new operator ++. This is called the increment operator, and in this case it's used to increment the value of the variable daysInAYear by 1 and assign it back to itself. The result of this operation is 366, as shown on line 5. The increment operator commonly used in loops, which will be discussed later on. We could have also written daysInAYear = daysInAYear + 1;, but ++ is a convenient shortcut to do the same thing. There is also a decrement operator -- which is the same as the increment operator, except it subtracts 1 instead of adding 1. It is illegal to apply the increment or decrement operator to a literal. For example:
int daysInALeapYear = 365++; //error, ++ should be applied to a variable instead of being applied directly to the literal 365
Operator Types
Now that we've seen some examples of operators in Java, let's take a more detailed look at the different groups of operators and what's available for us to use. There are four basic groups of operators: arithmetic, bitwise, relational, and logical. These are discussed in detail below:
Arithmetic operators
Arithmetic operators are used to perform basic mathematical computations with numbers (integers, doubles, etc). Here is the list of arithmetic operators, along with their description:
Operator Description
+ Addition
- Subtraction
* Multiplication
/ Division
% Modulus
+= Addition Assignment
-= Subtraction Assignment
*= Multiplication Assignment
/= Division Assignment
%= Modulus Assignment
++ Increment
-- Decrement
Most of these should look pretty familiar. The +, -, *, and / do what we'd expect. One thing to note is that dividing two integers will produce another integer and truncate (discard) the fractional part. For example, 8/3 would produce 2.6666667 on a standard calculator, but in Java, the fractional part is discarded and we are left with 2.
The % operator is known as the modulus operator and it is the remainder when the first number is divided by the second. For example 11/3 is 3 with a remainder of 2, so 11 % 3 = 2. And 12/3 is 4 with a remainder of 0, so 12 % 3 = 0. The modulus operator is commonly used to repeat a series of numbers. If I start with 0 and continually increment it by 1, and mod the result by 2, the answer will alternate between 0 and 1:
0 % 2 = 0
1 % 2 = 1
2 % 2 = 1
3 % 2 = 1
4 % 2 = 0
...
This could be useful when creating a table with alternating row colors. Another use could be time conversion. 10000 seconds is two hours (7200) with a remainder of 2800 seconds, which is equal to 46 minutes with a remainder of 40 seconds. It's worth noting that modulus can be performed on both positive and negative numbers. In that case, the sign of the result is the same as the sign of the first number:
-8 % 3; //-2, 8 % 3 = 2, but the first number is negative
-8 % -3; //also -2, since the first number is still negative
8 % -3; //2, since the first number is positive
I haven't come accross any uses of using % with negative numbers in real world projects, but it's worth noting in case you encounter that in other people's code.
The arithmentic assignment operators (+=, -=, *=, /=, and %=) behave similarly to +, -, *, /, and %, except that the result is assigned to the variable at the same time. For example, we could write something like:
int a = 4;
a = a + 2
but int a = 4; a += 2 is a convenient shorthand. The line a += 2 simply takes the value that was already to a, adds 2, and assigns the result back to a. These operators are also known as compound operators, because they do multiple things (perform arithmentic and assign the result) using a single operator.
The last two operators (++ and --) are a shorthand for the compound assignment operators. Specifically, ++ adds 1 and assigns the result back to the variable, and -- subtracts 1 and assigns the result back. Here is an example:
int x = 2;
x++; //x is now 3
x--; //x is now 2
x--; //x is now 1
System.out.println(x); //1
A common use of ++ and -- is to repeatedly increment or decrement a value by 1 in a loop. This will be covered in detail in a later post.
Bitwise operators
Bitwise operators can be applied to whole number types (long, int, short, byte, or even char), but they act upon the individual bits of a number instead of the numbers themselves. In order to understand bitwise operators, we must convert the numbers to binary form, as in these examples:
32 = 2^5 or 100000
47 = 2^5 + 2^3 + 2^2 + 2^1 + 2^0 or 101111
48 = 2^5 + 2^4 or 110000
If you're not familiar with converting numbers between decimal and binary, you'll be happy to know that the bitwise operators don't see a lot of use in actual Java programs. Nevertheless, let's take a look at the bitwise operators provided by the Java language:
Operator Description
& Bitwise and
| Bitwise or
~ Bitwise not (negation)
^ Bitwise exclusive or
&= Bitwise and assignment
|= Bitwise or assignment
^= Bitwise exclusive or assignment
>> Right shift
<< Left shift
>>= Right shift assignment
<<= Left shift assignment
>>> Right shift zero fill
>>>= Right shift zero fill assignment
Many of the bitwise operators don't see much usage, and it's a bit early in this blog to introduce all of them. For now, let's take a look at how the bitwise and/or works. Bitwise and converts the numbers to binary (base 2) notation and 'ANDs' the bits together from left to right. In other words, if both bits have a value of 1, the result is 1. If at least 1 of the bits is 0, the result is 0. Bitwise 'OR' works similarly, except if either of the two bits is 1 (or both bits are 1), then the result is 1. If both bits are 0, then the result is 0. Let's take a look at an example:
9 & 5
Step 1: convert 9 and 5 to binary
9 = 1001
5 = 0101
Step 2: 'AND' the bits together from left to right
0001 (Starting from the left, 1 & 0 = 0, 0 & 1 = 0, 0 & 0 = 0, 1 & 1 = 1)
Step 3: Convert the results back to base 10
Answer: 9 & 5 = 1
-----
And here's an example for bitwise OR:
9 | 5
Step 1: convert 9 and 5 to binary
9 = 1001
5 = 0101
Step 2: 'OR' the bits together from left to right
1101 (Starting from the left, 1 | 0 = 1, 0 | 1 = 1, 0 | 0 = 0, 1 | 1 = 1)
Step 3: Convert the results back to base 10
1101 = 8 + 4 + 1 = 13
Answer: 9 | 5 = 13
Not too bad, huh? Again, bitwise operators don't see much use in actual code. Some examples are compression, encryption, and low-level computer graphics operations. Let's move on to relational operators.
Relational Operators
Relational operators compare the value on the left with the value on the right and produce a boolean value (true or false). Here is the list of relational operators in Java:
Operator Description
== Equal to
!= Not equal to
> Greater than
< Less than
>= Greater than or equal to
<= Less than or equal to
These operators work in almost the same way as they do in math. One thing to note is that == and != can be applied booleans, while the other relational operators only apply to numbers. Here are some examples:
4 == 5 //false
4 != 5 //true
4 != 4 //false
5.5 > 3.2 //true
5.5 < 3.2 //false
5.5 >= 4 //true
5.5 >= 5.5 //true
5.5 <= 4 //false
'c' > 'a' //true, characters are internally stored as numbers in Java, so this is allowed. Letters later in the alphabet are considered greater than earlier letters
'c' == 'a' //false
true == false //false
true > false //error, > can only be applied to numbers
Relational operators are commonly used in conditional statements, which will be covered in the next section, so we'll get a lot more practice with these. Unlike the bitwise operators, relational operators are frequently used, and you can expect to see them in virtually every Java program.
Ternary Operator
The ternary operator (? symbol) is an alternative way to write certain types of conditional statments. It will be looked at in the next section.
Example
Now that you've seen the four types of operators (arithmetic, bitwise, relational, ternary), it's time to write a small program to test things out. This program will compute the area of a circle given it's radius. In order to make things a bit more interactive, I used a Scanner to read the user's input from the console. This is similar to the System.out.println() method we saw in an earlier post, except the scanner reads from the console instead of writing to it. Here is the full program:
import java.util.Scanner;
public class ExpressionsTest {
public static void main(String[] args) {
System.out.println("This program computes the area of a circle given the radius.");
System.out.print("Enter the radius of the circle in centimeters: ");
Scanner scanner = new Scanner(System.in);
double circleRadius = scanner.nextDouble();
double circleArea = circleRadius * 2 * Math.PI;
System.out.println("The area of the circle is " + circleArea + " centimeters");
scanner.close();
}
}
Apart from the code which creates the scanner and reads the input, most of this code should be straightforward. The line "double circleArea = circleRadius * 2 * Math.PI" is our arithmetic expression to convert the circle radius into an area. Math.PI is a built-in costant in the Java language that provides an approximation of pi. After printing out the area of the circle to the console, we close the scanner to avoid any resource leakage (this will be covered in more detail later). Here is a screenshot of the program in action:
With most of the basic expressions covered, it's time to move on to conditional statements and enhance our basic example.
3 //simple literal expression that results in a value of 3
3 + 4 //arithmetic expression resulting in a value of 7
(3 + 4) * 2 //more advanced arithmetic expression using order of operation, resulting in a value of 14
6 & 5 //bitwise expression resulting in a value of 4
3 >= 4 //relational expression resulting in a value of false
8 > 10 ? 15 < 20 ? 50 : 80 : 3 >= 2 ? 4 : 8; //very complicated expression using the ternary operator, resulting in a value of 4. Not recommended to use complicated expressions because it is difficult to read/modify
Sometimes people refer to expressions in java as operations. An operation in Java is similar to a mathematical operation - it modifies a value (or multiple values) to produce a new value. An operand is the variable or literal that is used in the operation. An operator is a symbol that is applied to the operand(s). This is best explained in an example:
int daysInAYear = 365;
int daysInThreeYears = daysInAYear * 3;
int daysInFiveYears = daysInThreeYears + daysInAYear * 2;
daysInAYear++; //leap year calculation
System.out.println(daysInAYear); //366
The first line is a simple assignment operation that takes the literal value 365 and copies it to the variable daysInAYear, which is of type integer. In this case, 365 is the operand, the = is the assignment operator that copies the value over, and daysInAYear is the result of the assignment operation (365).
The second line should be fairly straightforward. It takes daysInAYear and multiplies it by 3 to produce a new value daysInThreeYears. The variable daysInAYear and the literal 3 are the operands, and the * and = are the operators. What's interesting here is that the multiplication operator * takes two operands (daysInAYear and 3) while the assignment operator = only takes one (the result of daysInAYear * 3 = 1095). In Java, some operators take two operands and some only take one. Additionally, there is a ternary operator which takes 3 operands. This will be discussed later when we get to control statements.
The third line takes daysInThreeYears and 2 times daysInAYear to derive a new value which is assigned to daysInFiveYears. There are three operators +, *, and =. Similar to mathematics, the order in which these operators are applied is important. If daysInThreeYears + daysInAYear were calculated first, and then multiplied by 2, then the value returned would be the number of days in eight years (4 * 2). But the multiplication * operator has precedence over the + operator, so daysInAYear is first multiplied by 2 and then the result is added to daysInThreeYears, which results in the number of days in five years. Finally, the end result is assigned to the variable daysInFiveYears.
To recap, multiplication (*) has precedence over addition (+), which has precedence over assignment (=). This becomes more important as the calculations get more complex. Java provides parenthesis () to increase the precedence of the operation inside of it. For example, (daysInThreeYears + daysInAYear) * 2 would result in 8 * 365 = 2920, since the + is evaluated first, and then that result (4 * 365) is multiplied by 2. And daysInThreeYears + (daysInAYear * 2) would produce 5 * 365 = 1825, which is the same as the original expression daysInThreeYears + daysInAYear * 2. In this case, the parenthesis are unnecessary since * already has precedence over +. However, it is a good practice to include parenthesis in cases where other programmers might have a hard time figuring out what the order is. It's probably not needed in this simple example, but as operations get more complex, it really helps to see visually which parts of the operation are evaluated first. It's also a good idea to avoid overly complicated expressions and break them up in to multiple lines if needed. For example:
int daysInTwoYears = daysInAYear * 2;
int daysInFiveYears = daysInTwoYears + daysInThreeYears; //No confusion here, it's just a simple additon statement
In line 4, we come across a new operator ++. This is called the increment operator, and in this case it's used to increment the value of the variable daysInAYear by 1 and assign it back to itself. The result of this operation is 366, as shown on line 5. The increment operator commonly used in loops, which will be discussed later on. We could have also written daysInAYear = daysInAYear + 1;, but ++ is a convenient shortcut to do the same thing. There is also a decrement operator -- which is the same as the increment operator, except it subtracts 1 instead of adding 1. It is illegal to apply the increment or decrement operator to a literal. For example:
int daysInALeapYear = 365++; //error, ++ should be applied to a variable instead of being applied directly to the literal 365
Operator Types
Now that we've seen some examples of operators in Java, let's take a more detailed look at the different groups of operators and what's available for us to use. There are four basic groups of operators: arithmetic, bitwise, relational, and logical. These are discussed in detail below:
Arithmetic operators
Arithmetic operators are used to perform basic mathematical computations with numbers (integers, doubles, etc). Here is the list of arithmetic operators, along with their description:
Operator Description
+ Addition
- Subtraction
* Multiplication
/ Division
% Modulus
+= Addition Assignment
-= Subtraction Assignment
*= Multiplication Assignment
/= Division Assignment
%= Modulus Assignment
++ Increment
-- Decrement
Most of these should look pretty familiar. The +, -, *, and / do what we'd expect. One thing to note is that dividing two integers will produce another integer and truncate (discard) the fractional part. For example, 8/3 would produce 2.6666667 on a standard calculator, but in Java, the fractional part is discarded and we are left with 2.
The % operator is known as the modulus operator and it is the remainder when the first number is divided by the second. For example 11/3 is 3 with a remainder of 2, so 11 % 3 = 2. And 12/3 is 4 with a remainder of 0, so 12 % 3 = 0. The modulus operator is commonly used to repeat a series of numbers. If I start with 0 and continually increment it by 1, and mod the result by 2, the answer will alternate between 0 and 1:
0 % 2 = 0
1 % 2 = 1
2 % 2 = 1
3 % 2 = 1
4 % 2 = 0
...
This could be useful when creating a table with alternating row colors. Another use could be time conversion. 10000 seconds is two hours (7200) with a remainder of 2800 seconds, which is equal to 46 minutes with a remainder of 40 seconds. It's worth noting that modulus can be performed on both positive and negative numbers. In that case, the sign of the result is the same as the sign of the first number:
-8 % 3; //-2, 8 % 3 = 2, but the first number is negative
-8 % -3; //also -2, since the first number is still negative
8 % -3; //2, since the first number is positive
I haven't come accross any uses of using % with negative numbers in real world projects, but it's worth noting in case you encounter that in other people's code.
The arithmentic assignment operators (+=, -=, *=, /=, and %=) behave similarly to +, -, *, /, and %, except that the result is assigned to the variable at the same time. For example, we could write something like:
int a = 4;
a = a + 2
but int a = 4; a += 2 is a convenient shorthand. The line a += 2 simply takes the value that was already to a, adds 2, and assigns the result back to a. These operators are also known as compound operators, because they do multiple things (perform arithmentic and assign the result) using a single operator.
The last two operators (++ and --) are a shorthand for the compound assignment operators. Specifically, ++ adds 1 and assigns the result back to the variable, and -- subtracts 1 and assigns the result back. Here is an example:
int x = 2;
x++; //x is now 3
x--; //x is now 2
x--; //x is now 1
System.out.println(x); //1
A common use of ++ and -- is to repeatedly increment or decrement a value by 1 in a loop. This will be covered in detail in a later post.
Bitwise operators
Bitwise operators can be applied to whole number types (long, int, short, byte, or even char), but they act upon the individual bits of a number instead of the numbers themselves. In order to understand bitwise operators, we must convert the numbers to binary form, as in these examples:
32 = 2^5 or 100000
47 = 2^5 + 2^3 + 2^2 + 2^1 + 2^0 or 101111
48 = 2^5 + 2^4 or 110000
If you're not familiar with converting numbers between decimal and binary, you'll be happy to know that the bitwise operators don't see a lot of use in actual Java programs. Nevertheless, let's take a look at the bitwise operators provided by the Java language:
Operator Description
& Bitwise and
| Bitwise or
~ Bitwise not (negation)
^ Bitwise exclusive or
&= Bitwise and assignment
|= Bitwise or assignment
^= Bitwise exclusive or assignment
>> Right shift
<< Left shift
>>= Right shift assignment
<<= Left shift assignment
>>> Right shift zero fill
>>>= Right shift zero fill assignment
Many of the bitwise operators don't see much usage, and it's a bit early in this blog to introduce all of them. For now, let's take a look at how the bitwise and/or works. Bitwise and converts the numbers to binary (base 2) notation and 'ANDs' the bits together from left to right. In other words, if both bits have a value of 1, the result is 1. If at least 1 of the bits is 0, the result is 0. Bitwise 'OR' works similarly, except if either of the two bits is 1 (or both bits are 1), then the result is 1. If both bits are 0, then the result is 0. Let's take a look at an example:
9 & 5
Step 1: convert 9 and 5 to binary
9 = 1001
5 = 0101
Step 2: 'AND' the bits together from left to right
0001 (Starting from the left, 1 & 0 = 0, 0 & 1 = 0, 0 & 0 = 0, 1 & 1 = 1)
Step 3: Convert the results back to base 10
Answer: 9 & 5 = 1
-----
And here's an example for bitwise OR:
9 | 5
Step 1: convert 9 and 5 to binary
9 = 1001
5 = 0101
Step 2: 'OR' the bits together from left to right
1101 (Starting from the left, 1 | 0 = 1, 0 | 1 = 1, 0 | 0 = 0, 1 | 1 = 1)
Step 3: Convert the results back to base 10
1101 = 8 + 4 + 1 = 13
Answer: 9 | 5 = 13
Not too bad, huh? Again, bitwise operators don't see much use in actual code. Some examples are compression, encryption, and low-level computer graphics operations. Let's move on to relational operators.
Relational Operators
Relational operators compare the value on the left with the value on the right and produce a boolean value (true or false). Here is the list of relational operators in Java:
Operator Description
== Equal to
!= Not equal to
> Greater than
< Less than
>= Greater than or equal to
<= Less than or equal to
These operators work in almost the same way as they do in math. One thing to note is that == and != can be applied booleans, while the other relational operators only apply to numbers. Here are some examples:
4 == 5 //false
4 != 5 //true
4 != 4 //false
5.5 > 3.2 //true
5.5 < 3.2 //false
5.5 >= 4 //true
5.5 >= 5.5 //true
5.5 <= 4 //false
'c' > 'a' //true, characters are internally stored as numbers in Java, so this is allowed. Letters later in the alphabet are considered greater than earlier letters
'c' == 'a' //false
true == false //false
true > false //error, > can only be applied to numbers
Relational operators are commonly used in conditional statements, which will be covered in the next section, so we'll get a lot more practice with these. Unlike the bitwise operators, relational operators are frequently used, and you can expect to see them in virtually every Java program.
Ternary Operator
The ternary operator (? symbol) is an alternative way to write certain types of conditional statments. It will be looked at in the next section.
Example
Now that you've seen the four types of operators (arithmetic, bitwise, relational, ternary), it's time to write a small program to test things out. This program will compute the area of a circle given it's radius. In order to make things a bit more interactive, I used a Scanner to read the user's input from the console. This is similar to the System.out.println() method we saw in an earlier post, except the scanner reads from the console instead of writing to it. Here is the full program:
import java.util.Scanner;
public class ExpressionsTest {
public static void main(String[] args) {
System.out.println("This program computes the area of a circle given the radius.");
System.out.print("Enter the radius of the circle in centimeters: ");
Scanner scanner = new Scanner(System.in);
double circleRadius = scanner.nextDouble();
double circleArea = circleRadius * 2 * Math.PI;
System.out.println("The area of the circle is " + circleArea + " centimeters");
scanner.close();
}
}
Apart from the code which creates the scanner and reads the input, most of this code should be straightforward. The line "double circleArea = circleRadius * 2 * Math.PI" is our arithmetic expression to convert the circle radius into an area. Math.PI is a built-in costant in the Java language that provides an approximation of pi. After printing out the area of the circle to the console, we close the scanner to avoid any resource leakage (this will be covered in more detail later). Here is a screenshot of the program in action:
With most of the basic expressions covered, it's time to move on to conditional statements and enhance our basic example.
Sunday, July 16, 2017
Literals
In the last section, we took a brief look at assignment statements, which are used to associate a value with a variable. An example of this is:
double pi = 3.14159;
which assigns the value 3.14159 to the variable pi. This variable could be used in further calculations and expressions such as:
double radius = 2.5;
double circumference = 2 * pi * radius;
But before we get into all of the interesting things we can do with expressions, let's take a look at literals, which were used in the last section, but not fully explained.
Literals are numeric, boolean, character, and string values that are expressed directly in a program. In the example above, the value 3.14159 is the literal that is assigned to pi, and 2.5 is the literal that is assigned to radius. In the last line double circumference = 2 * pi * radius, there is only one literal. The values from pi and radius get substituted with their actual values when the program is run, and 2 is the only literal. We could just as easily have written double circumference = 2 * 3.14159 * 2.5, which has three literal values. But it would be difficult for others to understand where those numbers were coming from. For that reason, it's usually not a good idea to have lots of literals in the program. Sometimes people refer to those as "magic numbers" and say that we should avoid using too many magic numbers.
It's also possible to represent integer literals using octal (base 8) and hexadecimal (base 16) notation. Since 8 and 16 are powers of 2, it's easy to see the bit structure in octal and decimal numbers. This can be useful when writing certain types of programs, but using the standard (base 10) notation is preferred in most cases, since it's easier for people to read and understand. To represent a number using octal, the first digit most be a 0 and the other digits must be 0-7. To represent a number using hexadecimal, you must use a leading 0x, followed by 0-9 or A-F for the rest of the digits. The letters x and A-F are not case sensitive, so 0X4Bc1 would be legal. Here are some examples:
int diskBlockSize = 02000; //1024
int diskBlockSize = 08000; //error, all digits must be 0-7, 8 is not allowed in octal
int diskBlockSize = 0x400; //1024
int diskBlockSize = 0X400; //1024, capital X is also allowed
int diskBlockSize = 0x40G; //error, all digits must be 0-9 or A-F. G is not allowed in hexadecimal
int magicNumber = 0xA43B; //42023 (10 * 16^3 + 4 * 16^2 + 3 * 16 + 11 * 1)
Don't worry if you're not familiar with converting between octal and decimal numbers, or hexadecimal and decimal. These notations aren't used too often, and there are many octal and hexadecimal calculators/converters available online.
Boolean literals are pretty straightforward. A boolean literal is either the value true or false. No other values are allowed. For example, boolean isRaining = 0; would result in an error, since 0 is an integer literal and cannot be assigned to a boolean variable.
A character literal is a single letter inside of single quotes ''. More specifically, any Unicode character can be used as a character literal. Unicode is a way of representing text across a variety of languages and formats. It includes digits, letters, foreign characters, and math symbols, among other things. Unicode will be discussed in more detail in a later post. Non-printable characters can be entered using an escape sequence. An escape sequence consists of a backslash \ followed by a character, which indicates that the character should not be taken literally. For example, you cannot use the enter key to represent a newline character, it must be represented by the '\n' escape sequence. Similarly, the tab character can be represented using the '\t' escape sequence, although it is legal to use the tab key directly since the literal is still on one line. However, it's good practice to use the escape sequence so it's easy for others to see what the character is. Here are some examples of character literals being used:
char letter = 'b';
char digit = '0'; //Since the 0 is in single quotes, it is a character and not a number
char chineseLetter = '丧';
char greekLetter = 'φ';
char integralSign = '∫';
char tabCharacter = '\t';
char tabCharacter = ' '; //Legal, but not recommended. It's difficult to see what key was used to create the white space.
char newLineCharacter = '
'; //error, newlines are a non-printable character and need to be represented using '\n'
char newlineCharacter = '\n';
Floating-point literals consist of a decimal value with a fractional component, as discussed in the previous post. But there is another way of representing floating-point literals using scientific notation. This is done by adding an e (or E) at the end of the number, followed by a positive or negative number, indicating the power of 10 to multiply the numeric part by. As before, float types are represented using a f or F at the end. It's not necessary to do this for doubles, but an optional d or D can be added to the end. This is because floating-point literals default to double precision. Here are some examples:
double milesInLightYear = 5.879e+12;
double milesInLightYear = 5.879E12; //Legal, E can be both uppercase or lowercase. The + sign is not required for positive exponents
float milesInLightYear = 5.879e+12; //Error, floating types must end in f or F
float milesInLightYear = 5.879e+12F; //Legal
double electronChargeInCoulombs = 1.602e-19;
double electronChargeInCoulombs = 1.602-19; //Mistake, the e was left out, so this will result in 1.602 - 19 = -17.398 instead of 1.602e-19
The last type of literals are string literals. Strings are not a primitive type in Java, and haven't been discussed up to this point. A string consists of a sequence of characters between double quotes "". They can use the same escape sequences as characters. Whereas a character consists of a single letter, a string can contain many characters, making it more powerful. However, Strings are implemented as objects in Java, and have a few gotchas/edge cases. Strings are interesting enough to deserve a separate post later on. For now, here are some examples of String literals:
String name = "Bob";
String carModel = "Ford Escape";
String chineseCharacters = "丹东乸了伩";
String multiLineSentence = "Silence\nis\ngolden.";
Now that we understand all of the different types of literals, it's time to combine them to form powerful expressions using operators.
double pi = 3.14159;
which assigns the value 3.14159 to the variable pi. This variable could be used in further calculations and expressions such as:
double radius = 2.5;
double circumference = 2 * pi * radius;
But before we get into all of the interesting things we can do with expressions, let's take a look at literals, which were used in the last section, but not fully explained.
Literals are numeric, boolean, character, and string values that are expressed directly in a program. In the example above, the value 3.14159 is the literal that is assigned to pi, and 2.5 is the literal that is assigned to radius. In the last line double circumference = 2 * pi * radius, there is only one literal. The values from pi and radius get substituted with their actual values when the program is run, and 2 is the only literal. We could just as easily have written double circumference = 2 * 3.14159 * 2.5, which has three literal values. But it would be difficult for others to understand where those numbers were coming from. For that reason, it's usually not a good idea to have lots of literals in the program. Sometimes people refer to those as "magic numbers" and say that we should avoid using too many magic numbers.
It's also possible to represent integer literals using octal (base 8) and hexadecimal (base 16) notation. Since 8 and 16 are powers of 2, it's easy to see the bit structure in octal and decimal numbers. This can be useful when writing certain types of programs, but using the standard (base 10) notation is preferred in most cases, since it's easier for people to read and understand. To represent a number using octal, the first digit most be a 0 and the other digits must be 0-7. To represent a number using hexadecimal, you must use a leading 0x, followed by 0-9 or A-F for the rest of the digits. The letters x and A-F are not case sensitive, so 0X4Bc1 would be legal. Here are some examples:
int diskBlockSize = 02000; //1024
int diskBlockSize = 08000; //error, all digits must be 0-7, 8 is not allowed in octal
int diskBlockSize = 0x400; //1024
int diskBlockSize = 0X400; //1024, capital X is also allowed
int diskBlockSize = 0x40G; //error, all digits must be 0-9 or A-F. G is not allowed in hexadecimal
int magicNumber = 0xA43B; //42023 (10 * 16^3 + 4 * 16^2 + 3 * 16 + 11 * 1)
Don't worry if you're not familiar with converting between octal and decimal numbers, or hexadecimal and decimal. These notations aren't used too often, and there are many octal and hexadecimal calculators/converters available online.
Boolean literals are pretty straightforward. A boolean literal is either the value true or false. No other values are allowed. For example, boolean isRaining = 0; would result in an error, since 0 is an integer literal and cannot be assigned to a boolean variable.
A character literal is a single letter inside of single quotes ''. More specifically, any Unicode character can be used as a character literal. Unicode is a way of representing text across a variety of languages and formats. It includes digits, letters, foreign characters, and math symbols, among other things. Unicode will be discussed in more detail in a later post. Non-printable characters can be entered using an escape sequence. An escape sequence consists of a backslash \ followed by a character, which indicates that the character should not be taken literally. For example, you cannot use the enter key to represent a newline character, it must be represented by the '\n' escape sequence. Similarly, the tab character can be represented using the '\t' escape sequence, although it is legal to use the tab key directly since the literal is still on one line. However, it's good practice to use the escape sequence so it's easy for others to see what the character is. Here are some examples of character literals being used:
char letter = 'b';
char digit = '0'; //Since the 0 is in single quotes, it is a character and not a number
char chineseLetter = '丧';
char greekLetter = 'φ';
char integralSign = '∫';
char tabCharacter = '\t';
char tabCharacter = ' '; //Legal, but not recommended. It's difficult to see what key was used to create the white space.
char newLineCharacter = '
'; //error, newlines are a non-printable character and need to be represented using '\n'
char newlineCharacter = '\n';
Floating-point literals consist of a decimal value with a fractional component, as discussed in the previous post. But there is another way of representing floating-point literals using scientific notation. This is done by adding an e (or E) at the end of the number, followed by a positive or negative number, indicating the power of 10 to multiply the numeric part by. As before, float types are represented using a f or F at the end. It's not necessary to do this for doubles, but an optional d or D can be added to the end. This is because floating-point literals default to double precision. Here are some examples:
double milesInLightYear = 5.879e+12;
double milesInLightYear = 5.879E12; //Legal, E can be both uppercase or lowercase. The + sign is not required for positive exponents
float milesInLightYear = 5.879e+12; //Error, floating types must end in f or F
float milesInLightYear = 5.879e+12F; //Legal
double electronChargeInCoulombs = 1.602e-19;
double electronChargeInCoulombs = 1.602-19; //Mistake, the e was left out, so this will result in 1.602 - 19 = -17.398 instead of 1.602e-19
The last type of literals are string literals. Strings are not a primitive type in Java, and haven't been discussed up to this point. A string consists of a sequence of characters between double quotes "". They can use the same escape sequences as characters. Whereas a character consists of a single letter, a string can contain many characters, making it more powerful. However, Strings are implemented as objects in Java, and have a few gotchas/edge cases. Strings are interesting enough to deserve a separate post later on. For now, here are some examples of String literals:
String name = "Bob";
String carModel = "Ford Escape";
String chineseCharacters = "丹东乸了伩";
String multiLineSentence = "Silence\nis\ngolden.";
Now that we understand all of the different types of literals, it's time to combine them to form powerful expressions using operators.
Thursday, June 22, 2017
Dealing with Data Types
With all of the Java installation and configuration out of the way, it's time to look at some of the fundamental building blocks of the Java language. A main feature of all programming languages is that it should be able to manage data. This could range from something simple such as text entered by the user to complex, structured data such as thousands of parts in a warehouse and the corresponding supplier data. At the end of day though, all data can be broken down into simple values, such as numbers and text entries. For example, a part could be represented as a part/serial number and a name. The supplier could be represented by an ID, name, and address, which further breaks down to street address, city, and zip code. The most basic types of data supported by Java are called primitive types, which will be covered in this section. Later on, we'll see how to combine simple data entries into objects.
Java has 8 primitive types, which are based around numerical and character data. Numerical data can further be broken down into whole number (Integer) types and fractional (Floating point) numbers. The types are byte, short, int, long, float, double, boolean, and char. That may seem like a lot to take in, but a few of these types don't show up very much in actual programs. Typically, int, boolean, and double see the most usage, and the other types have more situational uses. Let's take a more detailed look at each type.
Byte
Bytes are the smallest integer type in Java. It is used to represent whole numbers from -128 to 127. Remember that all data is represented as bits (0s or 1s) on the computer. By using 8 bits, a byte can hold 2^8 = 256 possible values. These numbers are split evenly between positive and negative values, giving the range of -128 to 127. In practice most values can't be restricted to this range. For example, the number of days in a year could not be represented using a byte. Instead, bytes are most commonly used to manage binary data, such as data coming from the network or a a file. We'll see examples of this much later on.
Short
Shorts (and I don't mean the clothing) are used to represent whole numbers from -32,768 to 32,767. Shorts are composed of 16 bits, which gives 2^16 = 65,536 possible values. As before, half of the numbers are negative and the other half are positive. In practice, lots of values still don't fit into this range, such as the number of items in my local grocery store. For this reason, the short datatype doesn't see much use.
Int
Ints are 32 bit whole numbers, which gives a total of 2^32 = 4,294,967,296 possible values. The range of ints are from –2,147,483,648 to 2,147,483,647. This is large enough in most programs. Ints are commonly used in control statements and loops, which will be explained in future posts.
Long
Longs are 64 bit numbers ranging from –9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 (Approximately 9 quintillion). Since ints are usually large enough, you only need to use longs when dealing with large numbers. If longs still aren't big enough (for example, measuring astronomical distances), Java provides a BigInteger class, which is not a primitive type and incurs more overhead. However, it's unlikely that BigInteger is needed in most applications.
Float
Floats are used to represent decimal numbers using 32 bits. They have a range from about 1.4e–45 to 3.4e+38, and can be both positive or negative. Although that seems like a very large range, keep in mind that there are only 2^32 = 4,294,967,296 possible values that can be represented using 32 bits. This means that there is a loss of precision when storing numbers in floating point format. For example, due to how binary numbers work, it is impossible to represent the number .1 using a finite number of bits. The means that .1 might be stored as .0999994 when using floating point numbers. In general, floats have about 7 digits of precision, so decimal numbers with more than 7 digits may have roundoff errors. This can be a big deal in certain applications, such as banking systems, which require a high degree of accuracy when dealing with numbers.
Double
Doubles are basically the same as floats, except they use 64 bits instead of 32. This increases the amount of precision from 7 digits to 15. This makes double a better choice over floats most of the time. Surprisingly, some computers can perform mathematical functions faster on doubles than floats. This is because some processors deal directly with doubles and simulate floats by converting them to doubles. This isn't always true though, and it almost never makes a noticeable difference in speed. I recommend sticking with doubles over floats for the increased precision (at least until you really understand how floats and doubles work). Similar to BigInteger, there is a BigDouble class to represent decimal numbers that require more than 64 bits. Again, BigInteger and BigDouble are not primitive (built in) types, they are supported as an "extension" to the core Java language. BigDecimal usually isn't needed, but may come in handy when doing financial transactions.
Chars
Chars are used to store a single character using 2 bytes of memory. Characters are usually simple letters or numbers (A-Z, a-z, 0-9, etc), but could also be foreign symbols, such as Chinese or Japanese symbols. Chars are put inside of single quotes, such as 'a' or '源'. Since a byte is 8 bits, it's possible to store 2^16 = 65,536 different letters using a char, which is enough to cover all of the English letters and most of the foreign language symbols. Older languages, such as C, used 8 bits to store a character, which caused issues when working with foreign languages. There's a few edge cases such as certain language symbols or emojis that take more than 2 bytes to store, but they can still be used in Java.
Boolean
A boolean is a value that is either true or false. It may seem like booleans only take one bit to store since it can only have 2 possible values. However, the smallest unit of memory that can be addressed (looked up) in most computers is a byte (8 bits), so that is typically the size of a boolean. There are ways to represent boolean values using only 1 bit of memory, but with memory being so plentiful on modern computers, it's unlikely you'll need to do this. Booleans have their own set of unique operators. Integers/doubles can be added, multiplied, etc. Booleans can be combined with other booleans used and, or, not, and a few other operators to create more complicated boolean logic.
Now that we have a basic understanding of the basic data types in Java, it's time to look at declaring variables. A variable is simply a named reference that contains a data value. Variables are stored in memory and can be referenced later to retrieve their value. It's similar to using the memory button on a calculator to store the value of a previous computation. Let's look at some examples.
To declare a variable, use the format data-type variable-name;, where data-type is the type of variable (int, long, boolean, etc) and variable-name is the name you give to reference the variable later on. Variable names must should start with a letter and contain only letters, digits, or the underscore character _. Variable names can also start with a $ or _, but that is considered bad practice. Here are some examples of variable declarations:
int numPages; //valid
double age; //valid
boolean isSunday; //valid
float $amountEarned; //valid, but using $ is discouraged
char 1LetterWord; //error, variable name cannot start with a number
integer numPages; //error, integer is not a valid data type, use int instead
short if; //error, if is a reserved word
int numPages //error, semicolon is required at the end
As you can see in the examples, it is common to start the variable name with a lower case letter and put the first letter of subsequent words in upper case. This is called camel casing. Since variable names cannot contain a space, this convention makes it easy to identify where a word starts and ends in a variable name. Variable names should not start with an uppercase letter, as that convention is used for class names, which will be discussed in a later post. Also, variable names cannot be a keyword (also called a reserved word). These are words reserved by the Java language and include fundamental programming constructs things such as datatypes, conditionals, and loop control words (int, if, for, etc). Also, notice the ; is needed at the end of each variable declaration. Semicolons are used to terminate a statement, which is a complete unit of execution. You can think of a statement as a sentence and the ; is the period used to indicate where one sentence ends and another starts. Not every line of Java code is a statement and ends with a ;. Knowing when the ; is needed mostly comes with experience writing programs.
Declaring variables isn't too useful by itself, because the variables haven't been given a meaningful value. In some cases (for example, class fields) variables are automatically given a default value (0 for numbers and char, false for boolean). In other cases (method level variables) there is no default value given to a declared variable and it is an error to use it without providing a value first. Definitions solve this problem by giving the variable name and value at the same time. The format for defining a variable is data-type variable-name = value; Let's look at some examples:
int numPages = 300; //valid
double dollarToPeso = 18.15; //valid
char letter = 'x'; //valid
boolean isSunday = false; //valid
boolean isSunday = 0; //error, 0 is a number, not a boolean value
int numPages = 310.2; //error, 310.2 is not an integer;
char letter = "x"; //error, characters must be in single quotes, not double quotes
short daysInOneHundredYears = 36500; //error, 36500 is larger than 32767, the largest possible short
float dollarToPeso = 18.15; //error, floats values should have the letter f at the end
float dollarToPeso = 18.15f; //valid
int numPages = 2,000; //error, numbers must not contain a comma
int numPages = 2000 //error, ; is required at the end
Note that it is an error to assign a value that is incompatible with the type of variable. In the example above, numPages was an integer, but was given a value of 310.2, which is a double. Also, it is an error to assign a value that is outside the allowable range for that variable type. The daysInOneHundredYears variable was given a value of 36500, which is larger than the biggest short (32,767) and results in an error. Finally, notice that Java does not allow numbers to have commas. Instead, it is legal to use underscores _ to separate groups of digits in newer versions of Java (7+):
int numPagesInLibrary = 20_000_000; //legal in Java 7+
For now, this is a good starting point to using data types and variables in Java. Let's take a look at putting these concepts together in a sample application. I named the class VariableDeclarations. If you already created the HelloWorld class in Eclipse from the previous tutorial, you can right click on the class and select Refactor -> Rename, and then give the new name of the class. You can also create a new class inside the project if you'd like to keep the existing HelloWorld class as-is. Remember that for now, we're going to put everything inside the main method until we learn how to use classes and methods:
public class VariableDeclarations {
public static void main(String[] args) {
int numPages = 300; //valid
double dollarToPeso = 18.15; //valid
char letter = 'x'; //valid
boolean isSunday = false; //valid
float dollarToYen = 112.42f; //valid
long $companyEarnings = 4_000_000_000L; //valid, but using $ in the variable name is discouraged, and the L at the end is required since 4_000_000_000 is larger than the biggest int
// float dollarToPeso = 18.15; //error, floats values should have the letter f at the end
// Int numHolidays = 10; //error, java is case sensitive and data types must be lower case (int instead of Int)
// boolean isSunday = true; //error, isSunday was already declared above, it cannot be declared again;
// boolean isFriday = 0; //error, 0 is a number, not a boolean value
// int numBooks = 310.2; //error, 310.2 is not an integer;
// char anotherLetter = "x"; //error, characters must be in single quotes, not double quotes
// short daysInOneHundredYears = 36500; //error, 36500 is larger than 32767, the largest possible short
// int bookPublishedYear = 2,000; //error, numbers must not contain a comma
// int numAuthors = 3 //error, ; is required at the end
System.out.println(numPages);
System.out.println(dollarToPeso);
System.out.println(letter);
System.out.println(isSunday);
System.out.println(dollarToYen);
System.out.println($companyEarnings);
}
}
Try removing the // at the beginning of the lines that are marked with error, and see what error messages are displayed from Eclipse. Notice that System.out.println can take different data types and output them to the console as Strings (text). We'll learn how that works in a later post. The output of the program is what we'd expect:
300
18.15
x
false
112.42
4000000000
There's more to understand about variables, such as literals, operators, and expressions, which will be covered in the next section.
Java has 8 primitive types, which are based around numerical and character data. Numerical data can further be broken down into whole number (Integer) types and fractional (Floating point) numbers. The types are byte, short, int, long, float, double, boolean, and char. That may seem like a lot to take in, but a few of these types don't show up very much in actual programs. Typically, int, boolean, and double see the most usage, and the other types have more situational uses. Let's take a more detailed look at each type.
Byte
Bytes are the smallest integer type in Java. It is used to represent whole numbers from -128 to 127. Remember that all data is represented as bits (0s or 1s) on the computer. By using 8 bits, a byte can hold 2^8 = 256 possible values. These numbers are split evenly between positive and negative values, giving the range of -128 to 127. In practice most values can't be restricted to this range. For example, the number of days in a year could not be represented using a byte. Instead, bytes are most commonly used to manage binary data, such as data coming from the network or a a file. We'll see examples of this much later on.
Short
Shorts (and I don't mean the clothing) are used to represent whole numbers from -32,768 to 32,767. Shorts are composed of 16 bits, which gives 2^16 = 65,536 possible values. As before, half of the numbers are negative and the other half are positive. In practice, lots of values still don't fit into this range, such as the number of items in my local grocery store. For this reason, the short datatype doesn't see much use.
Int
Ints are 32 bit whole numbers, which gives a total of 2^32 = 4,294,967,296 possible values. The range of ints are from –2,147,483,648 to 2,147,483,647. This is large enough in most programs. Ints are commonly used in control statements and loops, which will be explained in future posts.
Long
Longs are 64 bit numbers ranging from –9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 (Approximately 9 quintillion). Since ints are usually large enough, you only need to use longs when dealing with large numbers. If longs still aren't big enough (for example, measuring astronomical distances), Java provides a BigInteger class, which is not a primitive type and incurs more overhead. However, it's unlikely that BigInteger is needed in most applications.
Float
Floats are used to represent decimal numbers using 32 bits. They have a range from about 1.4e–45 to 3.4e+38, and can be both positive or negative. Although that seems like a very large range, keep in mind that there are only 2^32 = 4,294,967,296 possible values that can be represented using 32 bits. This means that there is a loss of precision when storing numbers in floating point format. For example, due to how binary numbers work, it is impossible to represent the number .1 using a finite number of bits. The means that .1 might be stored as .0999994 when using floating point numbers. In general, floats have about 7 digits of precision, so decimal numbers with more than 7 digits may have roundoff errors. This can be a big deal in certain applications, such as banking systems, which require a high degree of accuracy when dealing with numbers.
Double
Doubles are basically the same as floats, except they use 64 bits instead of 32. This increases the amount of precision from 7 digits to 15. This makes double a better choice over floats most of the time. Surprisingly, some computers can perform mathematical functions faster on doubles than floats. This is because some processors deal directly with doubles and simulate floats by converting them to doubles. This isn't always true though, and it almost never makes a noticeable difference in speed. I recommend sticking with doubles over floats for the increased precision (at least until you really understand how floats and doubles work). Similar to BigInteger, there is a BigDouble class to represent decimal numbers that require more than 64 bits. Again, BigInteger and BigDouble are not primitive (built in) types, they are supported as an "extension" to the core Java language. BigDecimal usually isn't needed, but may come in handy when doing financial transactions.
Chars
Chars are used to store a single character using 2 bytes of memory. Characters are usually simple letters or numbers (A-Z, a-z, 0-9, etc), but could also be foreign symbols, such as Chinese or Japanese symbols. Chars are put inside of single quotes, such as 'a' or '源'. Since a byte is 8 bits, it's possible to store 2^16 = 65,536 different letters using a char, which is enough to cover all of the English letters and most of the foreign language symbols. Older languages, such as C, used 8 bits to store a character, which caused issues when working with foreign languages. There's a few edge cases such as certain language symbols or emojis that take more than 2 bytes to store, but they can still be used in Java.
Boolean
A boolean is a value that is either true or false. It may seem like booleans only take one bit to store since it can only have 2 possible values. However, the smallest unit of memory that can be addressed (looked up) in most computers is a byte (8 bits), so that is typically the size of a boolean. There are ways to represent boolean values using only 1 bit of memory, but with memory being so plentiful on modern computers, it's unlikely you'll need to do this. Booleans have their own set of unique operators. Integers/doubles can be added, multiplied, etc. Booleans can be combined with other booleans used and, or, not, and a few other operators to create more complicated boolean logic.
Declaring Variables
Now that we have a basic understanding of the basic data types in Java, it's time to look at declaring variables. A variable is simply a named reference that contains a data value. Variables are stored in memory and can be referenced later to retrieve their value. It's similar to using the memory button on a calculator to store the value of a previous computation. Let's look at some examples.
To declare a variable, use the format data-type variable-name;, where data-type is the type of variable (int, long, boolean, etc) and variable-name is the name you give to reference the variable later on. Variable names must should start with a letter and contain only letters, digits, or the underscore character _. Variable names can also start with a $ or _, but that is considered bad practice. Here are some examples of variable declarations:
int numPages; //valid
double age; //valid
boolean isSunday; //valid
float $amountEarned; //valid, but using $ is discouraged
char 1LetterWord; //error, variable name cannot start with a number
integer numPages; //error, integer is not a valid data type, use int instead
short if; //error, if is a reserved word
int numPages //error, semicolon is required at the end
As you can see in the examples, it is common to start the variable name with a lower case letter and put the first letter of subsequent words in upper case. This is called camel casing. Since variable names cannot contain a space, this convention makes it easy to identify where a word starts and ends in a variable name. Variable names should not start with an uppercase letter, as that convention is used for class names, which will be discussed in a later post. Also, variable names cannot be a keyword (also called a reserved word). These are words reserved by the Java language and include fundamental programming constructs things such as datatypes, conditionals, and loop control words (int, if, for, etc). Also, notice the ; is needed at the end of each variable declaration. Semicolons are used to terminate a statement, which is a complete unit of execution. You can think of a statement as a sentence and the ; is the period used to indicate where one sentence ends and another starts. Not every line of Java code is a statement and ends with a ;. Knowing when the ; is needed mostly comes with experience writing programs.
Defining Variables
Declaring variables isn't too useful by itself, because the variables haven't been given a meaningful value. In some cases (for example, class fields) variables are automatically given a default value (0 for numbers and char, false for boolean). In other cases (method level variables) there is no default value given to a declared variable and it is an error to use it without providing a value first. Definitions solve this problem by giving the variable name and value at the same time. The format for defining a variable is data-type variable-name = value; Let's look at some examples:
int numPages = 300; //valid
double dollarToPeso = 18.15; //valid
char letter = 'x'; //valid
boolean isSunday = false; //valid
boolean isSunday = 0; //error, 0 is a number, not a boolean value
int numPages = 310.2; //error, 310.2 is not an integer;
char letter = "x"; //error, characters must be in single quotes, not double quotes
short daysInOneHundredYears = 36500; //error, 36500 is larger than 32767, the largest possible short
float dollarToPeso = 18.15; //error, floats values should have the letter f at the end
float dollarToPeso = 18.15f; //valid
int numPages = 2,000; //error, numbers must not contain a comma
int numPages = 2000 //error, ; is required at the end
Note that it is an error to assign a value that is incompatible with the type of variable. In the example above, numPages was an integer, but was given a value of 310.2, which is a double. Also, it is an error to assign a value that is outside the allowable range for that variable type. The daysInOneHundredYears variable was given a value of 36500, which is larger than the biggest short (32,767) and results in an error. Finally, notice that Java does not allow numbers to have commas. Instead, it is legal to use underscores _ to separate groups of digits in newer versions of Java (7+):
int numPagesInLibrary = 20_000_000; //legal in Java 7+
For now, this is a good starting point to using data types and variables in Java. Let's take a look at putting these concepts together in a sample application. I named the class VariableDeclarations. If you already created the HelloWorld class in Eclipse from the previous tutorial, you can right click on the class and select Refactor -> Rename, and then give the new name of the class. You can also create a new class inside the project if you'd like to keep the existing HelloWorld class as-is. Remember that for now, we're going to put everything inside the main method until we learn how to use classes and methods:
public class VariableDeclarations {
public static void main(String[] args) {
int numPages = 300; //valid
double dollarToPeso = 18.15; //valid
char letter = 'x'; //valid
boolean isSunday = false; //valid
float dollarToYen = 112.42f; //valid
long $companyEarnings = 4_000_000_000L; //valid, but using $ in the variable name is discouraged, and the L at the end is required since 4_000_000_000 is larger than the biggest int
// float dollarToPeso = 18.15; //error, floats values should have the letter f at the end
// Int numHolidays = 10; //error, java is case sensitive and data types must be lower case (int instead of Int)
// boolean isSunday = true; //error, isSunday was already declared above, it cannot be declared again;
// boolean isFriday = 0; //error, 0 is a number, not a boolean value
// int numBooks = 310.2; //error, 310.2 is not an integer;
// char anotherLetter = "x"; //error, characters must be in single quotes, not double quotes
// short daysInOneHundredYears = 36500; //error, 36500 is larger than 32767, the largest possible short
// int bookPublishedYear = 2,000; //error, numbers must not contain a comma
// int numAuthors = 3 //error, ; is required at the end
System.out.println(numPages);
System.out.println(dollarToPeso);
System.out.println(letter);
System.out.println(isSunday);
System.out.println(dollarToYen);
System.out.println($companyEarnings);
}
}
Try removing the // at the beginning of the lines that are marked with error, and see what error messages are displayed from Eclipse. Notice that System.out.println can take different data types and output them to the console as Strings (text). We'll learn how that works in a later post. The output of the program is what we'd expect:
300
18.15
x
false
112.42
4000000000
There's more to understand about variables, such as literals, operators, and expressions, which will be covered in the next section.
Sunday, June 11, 2017
Using Eclipse IDE
In the last post, you learned how to create and run a basic Java application using a text editor and the command line. Although it's possible to create all Java applications with this approach, using an Integrated Development Environment (IDE) will greatly boost your productivity over using a standard text editor. IDEs have features such as automatic error checking, code formatting, syntax highlighting, integrated debugging, and auto complete. This makes writing Java programs much easier. In this post, we'll look at creating the Hello World program using an IDE.
The two main Java IDEs used in the industry are Eclipse and IntelliJ IDEA (also just called IntelliJ for short). IntelliJ has a free community edition and a paid ultimate edition, which requires a yearly fee of about $300-$500 USD. The community edition doesn't include a lot of the features in the ultimate edition, which is too expensive for most people. We are going to use Eclipse throughout this series. IntelliJ Ultimate includes a free trial version on its website https://www.jetbrains.com/idea/download if you're interested in trying it out. There are also a few other Java IDEs, such as NetBeans and BlueJ, which are less widely used.
To install Eclipse, go to the downloads page https://www.eclipse.org/downloads, and click on the "Download Packages" link as shown in the following screenshot:
The current version is Eclipse Neon, but new versions are released every year in June. Eclipse Oxygen is scheduled for release in late June, 2017. After going to the Download Packages page, you should see options such as these:
The two options of interest are Eclipse IDE for Java EE Developers and Eclipse IDE for Java Developers. The Java EE Developers version has everything in the Java Developers download, plus a few features for writing web applications. Either version should be sufficient for this series. To launch eclipse, simply unzip the folder that was downloaded and double-click on the eclipse program (icon with a purple circle). You may want to create a desktop shortcut for easy access in the future.
After running eclipse, you should see a prompt asking where you want to create the workspace. A workspace is a group of related projects that you are working on. For very large applications, you may need multiple workspaces, but usually one is enough. The following screenshot shows the directory for a sample workspace:
I recommend using a location such as "C:\Users\[your username]\workspace" on Windows and "/Users/[your username]/workspace" on Mac or Linux. It's a matter of preference, but what's important is that it's easy to remember where the workspace is. You'll also see a checkbox that says "Use this as the default and do not ask again". I recommend checking that so you don't see workspace prompts when launching Eclipse in the future.
After the workspace is set up, you'll be taken to the welcome page, as shown in the following screenshot:
The welcome page has several options to create a new project, update settings, etc. You can do all of this from the main page, so don't select those options. You'll also see a checkbox that says something like "Always show Welcome page at startup". I recommend unchecking that, so you don't see the startup page every time you launch Eclipse. To exit out of the welcome page, click on the "x" on the welcome tab at the top of the screen. After a moment, you should see the main workspace view, similar to the following:
Don't worry if the layout is a little different on your machine. I recommend having the Package Explorer view on the left, the Outline view on the right, and the Problems and Console view on the bottom of the screen. If you don't see those, you can select Window -> Show View -> Console/Package Explorer/Outline from the top menu, and drag that view over to the correct location on the screen. There are dozens of different views in Eclipse, and it's possible that you don't see the view you want on the list. In that case, you can select Window -> Show View -> Other, and then type the name of the view you want in the search box. In Eclipse, a view is simply a window or tab that you can use to perform various actions. Package explorer allows you to see the structure of the project, outline allows you to see the class structure, and console allows you to view the output from your program. We'll take a deeper look at views and other Eclipse options in a future post. For now, it's time to create our first program in Eclipse.
To do this, select File -> New -> Java Project from the main menu. You should see a dialog similar to the following:
Projects are used to organize different programs within your workspace. In this case, we want to create a project that we can use to learn Java basics. Under project name, type "JavaBasics". Project names should start with an uppercase letter, and must not contain spaces. You can keep the "Use Default Location" option checked, which will create the project underneath your workspace. For the JRE section, select the first radio button. You should see a version such as JavaSE-1.8 in the dropdown. Leave the Project layout and Working sets sections with the default values and click Finish. After a moment, you should see the JavaBasics project display in the Package Explorer view. Next, it is time to create our HelloWorld class.
Click on the JavaBasics project in the Package Explorer view, and select File -> New -> Class from the main menu. This will bring up the following dialog:
The source folder should be set to JavaBasics/src by default. That is the directory where the class will go under. By convention, Java source files go under the src folder. Leave the package option blank, and ignore the warning saying "The use of the default package is discouraged". We will learn about packages in a later post, so we will keep things simple and leave the package blank, even though it's not good practice. Under Name, enter "HelloWorld". This is the name of the class we are creating. Also, make sure that the public static void main (String[] args) method stub is checked and the others are not. This is important, as it allows Eclipse to automatically generate the main method, which saves us time and helps us avoid errors if we forget to add that method. Finally in the main view, we should see a HelloWorld.java tab with code similar to the following:
As we can see, the HelloWorld class and main method was automatically generated for us. How convenient! The "//TODO Auto-generated method stub" line tells us that we can put our code inside of there. The "//" character sequence is used to start a comment, which is a human-readable description that gets ignored by the Java compiler. This can be useful for other developers to understand your thought process when writing a piece of code. I recommend deleting this comment, because other developers should already know that Eclipse can automatically generate methods.
Another important feature that Eclipse provides is called autocomplete (also called intellisense). As the name suggests, Eclipse will try to give helpful guesses about what you are typing to save effort. For example, the command System.out.println("[some message]") is used in many programs to display a message on the console. Instead of having to type System.out.println each time, you can simply type sysout and hit "command + space". This will cause eclipse to automatically generate the System.Out.Println() command. Try this out by typing sysout on a blank line inside the main method, and check that Eclipse generates the full System.Out.Println() output. Very convenient! In case there are multiple options matching what you typed, Eclipse will display a dropdown with the list of possible autocomplete options. For example, try typing syso and hitting "command + space". You should see a popup similar to the following:
Simply use the up and down arrow keys to select the right option and press enter for Eclipse to do the autocomplete. In this case, we want to select the sysout option, which should be the first one in the list.
To finish our HelloWorld program, enter some System.Out.Println() statements in the main method. You should have something similar to this:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
System.out.println("This is my first program from Eclipse!");
}
}
To run the program, expand the JavaBasics project in the Package Explorer view, and expand the src and default package entries. Right click on the HelloWorld.java class and select Run As -> Java Application fromt the menu. If everything goes well, you should see this output in the console view:
Congratulations! You have created your first Java program from Eclipse. We've barely scratched the surface on what the Eclipse IDE can do, but we can see already see the autocomplete and code autogeneration functionality saves us time and effort. One last feature I want to point out in this post is that Eclipse can automatically detect errors and tell us what is going wrong. For example, try deleting the ";" at the end of the System.out.println("Hello World!"); line. Eclipse will underline the mistake in red squiggly line, and we can hover over that (or the red X at the beginning of the line) to see what the error is:
In this case, eclipse tells us that ";" is needed to complete block statements. You'll get better at identifying and understanding what these error messages mean as you continue to write more programs. After adding the ";" back, we can see that the error message goes away, and we're able to run our program as before. We have covered a lot of ground in this post on how to install Eclispe and run our first application. It's time to start learning about basic Java programming in the next section!
The two main Java IDEs used in the industry are Eclipse and IntelliJ IDEA (also just called IntelliJ for short). IntelliJ has a free community edition and a paid ultimate edition, which requires a yearly fee of about $300-$500 USD. The community edition doesn't include a lot of the features in the ultimate edition, which is too expensive for most people. We are going to use Eclipse throughout this series. IntelliJ Ultimate includes a free trial version on its website https://www.jetbrains.com/idea/download if you're interested in trying it out. There are also a few other Java IDEs, such as NetBeans and BlueJ, which are less widely used.
To install Eclipse, go to the downloads page https://www.eclipse.org/downloads, and click on the "Download Packages" link as shown in the following screenshot:
The current version is Eclipse Neon, but new versions are released every year in June. Eclipse Oxygen is scheduled for release in late June, 2017. After going to the Download Packages page, you should see options such as these:
The two options of interest are Eclipse IDE for Java EE Developers and Eclipse IDE for Java Developers. The Java EE Developers version has everything in the Java Developers download, plus a few features for writing web applications. Either version should be sufficient for this series. To launch eclipse, simply unzip the folder that was downloaded and double-click on the eclipse program (icon with a purple circle). You may want to create a desktop shortcut for easy access in the future.
After running eclipse, you should see a prompt asking where you want to create the workspace. A workspace is a group of related projects that you are working on. For very large applications, you may need multiple workspaces, but usually one is enough. The following screenshot shows the directory for a sample workspace:
I recommend using a location such as "C:\Users\[your username]\workspace" on Windows and "/Users/[your username]/workspace" on Mac or Linux. It's a matter of preference, but what's important is that it's easy to remember where the workspace is. You'll also see a checkbox that says "Use this as the default and do not ask again". I recommend checking that so you don't see workspace prompts when launching Eclipse in the future.
After the workspace is set up, you'll be taken to the welcome page, as shown in the following screenshot:
The welcome page has several options to create a new project, update settings, etc. You can do all of this from the main page, so don't select those options. You'll also see a checkbox that says something like "Always show Welcome page at startup". I recommend unchecking that, so you don't see the startup page every time you launch Eclipse. To exit out of the welcome page, click on the "x" on the welcome tab at the top of the screen. After a moment, you should see the main workspace view, similar to the following:
Don't worry if the layout is a little different on your machine. I recommend having the Package Explorer view on the left, the Outline view on the right, and the Problems and Console view on the bottom of the screen. If you don't see those, you can select Window -> Show View -> Console/Package Explorer/Outline from the top menu, and drag that view over to the correct location on the screen. There are dozens of different views in Eclipse, and it's possible that you don't see the view you want on the list. In that case, you can select Window -> Show View -> Other, and then type the name of the view you want in the search box. In Eclipse, a view is simply a window or tab that you can use to perform various actions. Package explorer allows you to see the structure of the project, outline allows you to see the class structure, and console allows you to view the output from your program. We'll take a deeper look at views and other Eclipse options in a future post. For now, it's time to create our first program in Eclipse.
To do this, select File -> New -> Java Project from the main menu. You should see a dialog similar to the following:
Projects are used to organize different programs within your workspace. In this case, we want to create a project that we can use to learn Java basics. Under project name, type "JavaBasics". Project names should start with an uppercase letter, and must not contain spaces. You can keep the "Use Default Location" option checked, which will create the project underneath your workspace. For the JRE section, select the first radio button. You should see a version such as JavaSE-1.8 in the dropdown. Leave the Project layout and Working sets sections with the default values and click Finish. After a moment, you should see the JavaBasics project display in the Package Explorer view. Next, it is time to create our HelloWorld class.
Click on the JavaBasics project in the Package Explorer view, and select File -> New -> Class from the main menu. This will bring up the following dialog:
The source folder should be set to JavaBasics/src by default. That is the directory where the class will go under. By convention, Java source files go under the src folder. Leave the package option blank, and ignore the warning saying "The use of the default package is discouraged". We will learn about packages in a later post, so we will keep things simple and leave the package blank, even though it's not good practice. Under Name, enter "HelloWorld". This is the name of the class we are creating. Also, make sure that the public static void main (String[] args) method stub is checked and the others are not. This is important, as it allows Eclipse to automatically generate the main method, which saves us time and helps us avoid errors if we forget to add that method. Finally in the main view, we should see a HelloWorld.java tab with code similar to the following:
As we can see, the HelloWorld class and main method was automatically generated for us. How convenient! The "//TODO Auto-generated method stub" line tells us that we can put our code inside of there. The "//" character sequence is used to start a comment, which is a human-readable description that gets ignored by the Java compiler. This can be useful for other developers to understand your thought process when writing a piece of code. I recommend deleting this comment, because other developers should already know that Eclipse can automatically generate methods.
Another important feature that Eclipse provides is called autocomplete (also called intellisense). As the name suggests, Eclipse will try to give helpful guesses about what you are typing to save effort. For example, the command System.out.println("[some message]") is used in many programs to display a message on the console. Instead of having to type System.out.println each time, you can simply type sysout and hit "command + space". This will cause eclipse to automatically generate the System.Out.Println() command. Try this out by typing sysout on a blank line inside the main method, and check that Eclipse generates the full System.Out.Println() output. Very convenient! In case there are multiple options matching what you typed, Eclipse will display a dropdown with the list of possible autocomplete options. For example, try typing syso and hitting "command + space". You should see a popup similar to the following:
Simply use the up and down arrow keys to select the right option and press enter for Eclipse to do the autocomplete. In this case, we want to select the sysout option, which should be the first one in the list.
To finish our HelloWorld program, enter some System.Out.Println() statements in the main method. You should have something similar to this:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
System.out.println("This is my first program from Eclipse!");
}
}
To run the program, expand the JavaBasics project in the Package Explorer view, and expand the src and default package entries. Right click on the HelloWorld.java class and select Run As -> Java Application fromt the menu. If everything goes well, you should see this output in the console view:
Congratulations! You have created your first Java program from Eclipse. We've barely scratched the surface on what the Eclipse IDE can do, but we can see already see the autocomplete and code autogeneration functionality saves us time and effort. One last feature I want to point out in this post is that Eclipse can automatically detect errors and tell us what is going wrong. For example, try deleting the ";" at the end of the System.out.println("Hello World!"); line. Eclipse will underline the mistake in red squiggly line, and we can hover over that (or the red X at the beginning of the line) to see what the error is:
In this case, eclipse tells us that ";" is needed to complete block statements. You'll get better at identifying and understanding what these error messages mean as you continue to write more programs. After adding the ";" back, we can see that the error message goes away, and we're able to run our program as before. We have covered a lot of ground in this post on how to install Eclispe and run our first application. It's time to start learning about basic Java programming in the next section!
Subscribe to:
Posts (Atom)