Practical OCA Java SE 8 Programmer I Certification Guide (Working with Java Data Types) pdf pdf

  Practical OCA Java SE 8 Programmer I: Certification Guide Table of Contents

  char data type int data types byte short int long number systems decimal binary octal hexadecimal combined number system manipulation floating point number data types float double boolean data type

  Introduction of underscores to our literal values Identifiers Identifier rules Differentiate between object reference variables and primitive variables. Differences between object reference and primitive variables Know how to read or write to object fields. Explain an Object's Lifecycle (creation, "dereference by reassignment" and garbage collection).

  Introduction to garbage collection Object creation dereference by reassignment garbage collection

  Develop code that uses wrapper classes such as Boolean, Double, and Integer.

  Introduction to Wrapper classes Assignment Constructor Static method Retrieving primitive values from the wrapper classes Parsing a string value to a primitive value Constructor and valueOf method Compare objects of wrapper classes Auto-boxing and un-boxing

  About the author

My name is Marks Bhele and I have over 10 years of experience in the IT industry as a Developer. I am

currently working for a major bank as a Java Developer. I also have extensive experience in programming using PHP.

  

I have 6 years of lecturing experience. I have lectured at a college for four years and two years at a high

school. I tried moving away from teaching; but the love I have for sharing my knowledge is

unquenchable. So I decided to juggle both teaching online and working as a Java Developer at the same

time.

  Who is this eBook for?

This eBook is not an introduction to Java by any means. It is assumed that the reader has had some Java

programming experience or familiarity.

  I wrote this eBook specifically for those who want to pursue OCA Java SE 8 Programmer I

Certification: Exam number 1Z0-808. I have covered all the exam objectives for the topic Working

with Java Data Types as laid out on the Oracle website.

  How to use this eBook? You need to run all the programs on your PC. If you don’t, you will be wasting your time as the

approach to this eBook is practical-oriented. If you adopt this approach, you will benefit more from this

eBook. Please have the relevant software installed before doing anything. Please install JDK 8 and any

IDE of your choice.

  Contact author You can contact me on this email address: Please use this email address to report any errors you find in this eBook.

Copyright

  Copyright © 2017 by Xecson (Pty) Ltd All rights reserved. This eBook or any portion thereof may not be reproduced or used in any manner whatsoever without the express written permission of the publisher except for the use of brief quotations in a book review.

Working with Java Data Types Objectives

  Declare and initialize variables (including casting of primitive data types). Differentiate between object reference variables and primitive variables. Know how to read or write to object fields. Explain an Object's Lifecycle (creation, "dereference by reassignment" and garbage collection). Develop code that uses wrapper classes such as Boolean, Double, and Integer.

Declare and initialize variables (including casting of primitive data types) Exam Objective 6 Primitive variables

  In Java, we have 8 simple data types that are used to declare variables. We have the following data types and we will look into them individually to understand how they are used:

  ü char ü byte ü short ü int ü long ü float

  ü double ü boolean

  Please note that these simple data type names are java keywords. Each data type is meant to hold a specific kind of data. If a variable is assigned incorrect kind of data to hold; we will get a compile error. Let’s now look at each data type individually and understand how it is manipulated.

  char data type

  This data type has a char keyword representing character(s). The char data type is an unsigned integer data type; meaning it can only hold data without negative numbers. We will explain later why we talk about numbers whereas this data type is meant only for characters. This data type can store a single

  16-bit Unicode character. That means it can store any character including Chinese letters, French letters and etc.

  The data type is unsigned and it has a corresponding wrapper class called Character which we will explain later. Java is a strongly typed language. This means all variables must be declared before they are used. You specify the data type, the identifier and the value the variable should hold.

  Let’s now declare a variable of type char and initialize it to a value.

  char ch = 'F';

  I have declared a variable ch of type char and initialized it to F. This is a valid code. But please note that we use single quotes around our literal value. A literal is a fixed value that doesn’t need further calculations in order for it to be assigned to any variable. Remember that a character is a single value inside single quotes. We can even have a number made a character. For example: char n = '5';

  The code is valid, because we put single quotes around the number. Let us now try and put more than one character in a variable of type char. For instance:

  char n = 'Marks';

  The code fails to compile because, a char type expects a single value inside single quotes. Let’s go back to our example where declared variable ch.

  char ch = 'F';

  We declared data type char and identifier ch as our variable name and then initialized ch to value F. This is how we declare a variable and initialize it. Initialization doesn’t have to be done on the same line. This code is equivalent to the one we have just seen:

  char ch; ch = 'F';

  We declare the variable first and then assign a value to it on the next line. Let us try and put double quotes around a char value and see what happens:

  char ch = "F";

  We get a compile error as this is not allowed. The error is as follows:

  Incompatible types: String cannot be converted to char Remember when we started off this chapter, I mentioned that char type is an unsigned integer type. That indicates to me that we can store a positive integer in a char variable. Let’s try this and see what happens:

  char ch = 130;

  Please note when we assign a number to ch variable, it should not be surrounded by single quotes. The result from running this code is ? (a question mark). This is interesting.

  char ch = 115;

  This code gives me s as the result. So what is happening here? char data type is stored internally as an unsigned integer value; that is only positive numbers.

  char ch = 97; stores value a char ch = 122; store value z 98 = b, 99 = c……y = 121, etc

  We said char data type stores unsigned integer values; that is only positive numbers. Let’s see what happens when we try to store negative numbers.

  char ch = -97;

  This code throws a syntax error. Code fails to compile. We cannot assign signed integers; only unsigned integers can be assigned. But we can actually force this negative value into our ch variable. For this to happen, we need to do casting; meaning we convert from one data type to another. When we cast, we put the data type we are converting into before the value we intend converting. But be careful of casting as you might get unexpected results. Remember positive 97 represents letter a. Let us now see what we get when we cast this negative number:

  char ch = (char)-97;

  The result was unexpected as I pointed out earlier on. Here is the result: ?

  (char) simply means convert value -97 to character value. This is casting in

  action. Casting should be done between compatible types. We will learn more about casting in the next sections of this chapter. When you declare variables, you can declare as many as you want on one line and then initialize them at the same time on the same line. Or alternatively, you can declare some and initialize them immediately and initialize others later. Let us look at the examples:

  char a, b, c, d, e; char a, b = 'b', c, d, e = 'e'; char a = 'a', b = 'b', c = 'c', d = 'd', e = 'e'; char a; //line 1 char b; //line 2 char c; //line 3 char d; //line 4 char e; //line 35

  On the first line, we declared variables without initializing them. This means initialization should happen before we can use these variables. On the second line, we declared variables and initialized only one variable. This means other variable should be initialized somewhere before they can be used. On line three, we declared our variables and initialized all of them. On the lines with comments ranging from line 1 to line 5; I declared variables separately which are not initialized. Before using these variables, you would need to initialize them first.

  

Note: This kind of declaration and initialization on the first three lines works

  only if the variables are of the same data type. This applies to all the other primitive types that we still have to tackle.

  int data types

  The data type int is a singed data type; meaning it takes both positive and negative numbers. Integer data type has sub categories namely: bye, short,

  long. The difference between these four type of integers (that is: int, byte, short and long) is the size. Each of them can store a different range of

  values. I’ll tackle them from the smallest; in terms of size; to the biggest range of values. The reason we have different sizes for integers is because, we store numbers based on our needs. If I have a need for small numbers, I’ll use a smaller integer data type. If I have a need to store long numbers, I’ll use a bigger integer data type, etc.

  byte integer data type

  The range for this integer type is 8 bits. The range of values you can store here is between -127 to 128. Let us now declare a variable of type byte.

  byte num = 90;

  I declared a simple variable of type byte and assigned 90 to it. Remember this is the only integer data type of which you need to remember its range of values for the exam. That is -127 to 128. You don’t have to memorize the range of values for other integer data types; that is short, long and int.

  I am now going to declare a variable with a range bigger than 128 and see what happens:

  byte num = 200;

  This line of code doesn’t compile. Remember the range of values for a byte variable? That is the reason the code fails to compile. Let’s try another example that is out of range:

  byte num = -130;

  This line of code fails to compile. The value assigned to the variable is out of range.

  We are now going to declare two byte variables and add their values together to get a sum. Since we work we byte data type, I’ll have the variable storing sum declared as of data type byte as well.

  byte num1 = 20; byte num2 = 70; byte sum = num1 + num2;

  I have declared variable num1, num2 and sum and they are all of data type

  byte. Surprisingly, on compiling this code; I get a compile error: Incompatible types: possible lossy conversion from int to byte.

  Why? The sum should be 90; a value that is within the range for a byte value. Remember the range of values for a byte is -127 to 128. So what is happening here? Before we answer this question, let’s change the variable type of sum to int.

  byte num1 = 20; byte num2 = 70; int sum = num1 + num2;

  When I run this code, I get no errors. Let us go back to our error message where sum is declared as a byte. It looks like when byte values are used in an expression; that is calculations; they are up-cast to an int type. This means the byte values are promoted to int type. Our variable to store sum; that is the calculated value; is declared as a byte. Remember an int type is far bigger than a byte. So the calculated value cannot be forced into a smaller data type from a bigger one which is int. Hence when we declare sum variable as int, our code works.

  But you might be asking, why can’t we store 90 in a byte variable because the value 90 is well within the range of values for data type byte? After applying byte values to calculations, the answer becomes an int by default. So now we are going to force this value 90 into the byte variable. This conversion from a bigger data type to a smaller data type is not allowed by the compiler. We need to tell the compiler explicitly somehow to say that it is our intention to force 90 into a byte variable. How do we do that? By casting our sum in this fashion: byte sum = (byte) (num1 + num2);

  Now the code compiles. We actually calculated our sum and then took the result and cast it into a byte value by applying (byte) parentheses and the data type we are converting into inside the parentheses. Or alternatively, we could have cast each variable to byte and then cast again the sum to byte as follows:

  byte sum = (byte) ((byte) num1 + (byte) num2); short integer data type Everything that applied to byte data type applies to short data type as well.

  The only major difference is the size for the range of values that a short variable can hold. The size of this data type is 16-bits with values ranging from -32,768 to 32,767. Please don’t memorize the range of values. It’s clear that a variable of type short can store bigger values than a byte variable. Please also note that all integer data types are signed.

  Let’s now see what happens when we manipulate variables of type short in the form of calculations. Will we have the same problems as was the case with byte data type? Will our results after calculation be up-cast to an int which is way bigger than the short variable?

  short num1 = 20; short num2 = 70; short sum = num1 + num2;

  The code does not compile. Variable sum is up-cast to an int variable. So we have two options here. Either to change the variable sum to int data type or leave it as it is and then force our result of calculation to short data type by casting. I’ll now have a code showing both options as follows:

  int sum = num1 + num2; or short sum = (short) (num1 + num2);

  Either of these options is correct to make the code compile. What happens when we add a value stored in a variable of type byte and a value stored in a variable of type short? Will the result be up-cast to int or will it be of type short? Let’s see the example:

  short num1 = 20; byte num2 = 70; short sum = num1 + num2;

  Code doesn’t compile. It is actually up-cast to int data type. The solution to get this code to compile is as follows:

  int sum = num1 + num2; or short sum = (short) (num1 + num2); or byte sum = (byte) (short) (num1 + num2);

  Either of these options makes our code compile. I have included the byte as well, because the sum is less than 128 which is the highest range of value for byte data type. What if the value of num1 is set to 200? That means our sum will be equal to 270 which is way bigger than range of values for a byte. Would byte data type still work here? Let’s see:

  short num1 = 200; byte num2 = 70; byte sum = (byte) (short) (num1 + num2); Yes, the code compiles. But the result is weird. Instead of 270, we got 14.

  Please be careful when you do casting as you might end up getting strange results. Let’s now try and store a value of type byte into a variable of type short.

  byte num1 = 90; short num = num1;

  This code compiled successfully. Why? Remember a variable of type short is bigger than the variable of type byte in terms of size. In other words, you can store a value of type byte into a variable of type long without casting. Is the opposite also correct? Can we store a value of type short into byte data type variable? Let’s try:

  short num1 = 90; byte num = num1;

  There is a compile error though. Why? A variable of type byte is smaller than variable of type short. Since we know the value 90 is within the range of values for a byte; we can do casting here as follows for our code to compile:

  short num1 = 90; byte num = (byte) num1; int integer data type

  int data type is the same as both byte and short data types. The difference is in the size; that is range of values it can store. This data type has a size of 32 bits. int data type is bigger than short data type. It has a range of

  2,147,483,648 to 2,147,483,647. You need not memorize the numbers. But

  be sure you can recall a range of values for the byte data type which is -127 to 128.

  Remember when we did our calculation using variables of type byte? The variable storing the result was up-cast to an int variable. Remember when we did calculations using variables of type short? Our variable storing the result was up-cast to an int data type. Remember when we did our calculation using a combination of variable of byte data type and a variable of data type short? Our variable storing the result was up-cast to int. The answer is yes to all of these questions.

  Any non decimal value defaults to the data type int. This refers to any value that does not have decimal places. That is a whole number like 90, not 90.0. This is evident when we do the calculations. Let us see a few examples of variables of type int: int num1 = 90; int num2 = 10; int sum = num1 + num2;

  This code works as expected. The result is 100 and it is of type int. Let’s have another example:

  int num1 = 90; byte num2 = 10; int sum = num1 + num2;

  The code worked. Variable num2, which is of type byte, was up-cast to an int variable. Let us now combine variables of both data types: byte and short.

  short num1 = 90; byte num2 = 10; int sum = num1 + num2;

  Both variables; num1 of type short and num2 of type byte; were up-cast to an integer and our program compiled. The result of the calculation was stored in the variable sum which is of type int. Can we do casting from int to short or byte? Yes we can; provided the sum is within the range of values to which we want to cast. Let’s cast our variable sum of type int to byte:

  int num1 = 90; int num2 = 10; byte sum = (byte) ((byte)num1 + num2);

  This code gave the expected result which is 100. There was no loss of any data nor was there any weird result. This is because the value of variable sum is within the range of values for a byte variable. Let’s change value 90 t0 200 and see what happens:

  int num1 = 200; int num2 = 10; byte sum = (byte) ((byte)num1 + num2);

  The code compiles because 200 can fit in a variable of type int. But when we cast to byte; that is when we run into problems because, a byte variable cannot accommodate a number over 128? Remember why? Let’s see the result of this code:

  • -14

  What? The casting gave us a weird result. Please be careful when you do casting. Know the expected result beforehand and compare it to the one the program gives you. Let’s explain again what a literal value is! A literal value is a fixed value that does not need any further calculations in order for it to be assigned to a variable. For example:

  int age = 10; short num1 = 9;

  I have assigned literal values to these variables. Let me show you an incorrect literal value:

  int age = 10; int num1 = age + 3; // Incorrect literal value. long integer data type

  This is also an integer data type with a much bigger size than all the other integer types. Its size is far bigger than the integer. long has a size of 64 bits. Long data type has a range of values from –9,223,372,036,854,775,808 to 9,223,372,036,854,775,807. Please say this number for me.

  Remember, I said any whole number is regarded as an integer. A whole number is a number without decimal places. For instance 10 is a whole number. 20.09 is not a whole number. Now there is a little twist when we declare a variable of type long. Let’s declare a variable using the keyword

  long and see how this is done. long salary = 1100;

  I have declared a variable of type long and initialized it to 1100. The value of salary is actually an int value stored in a variable of type long. This must be confusing hey! Ok, here is the thing: to explicitly make this literal value long, we add the suffix L or l to it. It is either uppercase L or lowercase l. Let’s see an example:

  long salary = 1100L;

   or long salary = 1100l;

  These two lines of code are equivalent. I’d suggest you use uppercase L, because lowercase l looks like number one and it can be confusing sometimes. Suppose we want to do some addition using variables of type byte, short and int. And then we store the result of our calculation in a long variable. Do we cast our result to int or do we keep our result in a variable of type long without up-casting? Let’s see an example and judge from there:

  byte num1 = 20; short num2 = 6; int num3 = 34; long sum = num1 + num2 + num3; System.out.println(sum); The result of this code is as follows:.

  type byte and initialized it to 20. I have also declared variable num2 of type short and initialized to 6. I have also declared a variable num3 of type int and initialized it to 34. Lastly I have declared variable sum and it is of type long. After addition, the answer is an int. I have stored sum which is of type int into a long variable. This is possible because, long type is big enough to accommodate an int value. Remember int has a size of 32 bits and long has a size of 64 bits. We don’t need any casting taking place to store int value in a long variable. int value is cast implicitly to long. But if we wanted to store a long value in an int variable, we would need to do explicit down-casting. Let us now change one of our variables to long data type and also change sum variable to int data type.

  Let’s see an example of down-casting a long to int.

  byte num1 = 20; long num2 = 6L; int num3 = 34; int sum = (int) ((int)num1 + num2 + num3); System.out.println(sum);

  I have changed the data type of num2 to long. This means the result of our calculation will be long. Remember we are adding byte, long and int values. So the result will be stored as long since it is the biggest data type used in this calculation. Now we are not allowed to store a long value in an int variable. We needed to down-cast our result to an int data type. Hence we were able to store a long value in an int variable. We did what we call down-casting.

  Do you know why our down-casting worked and we didn’t get any weird result? Because the value we have as a result of our calculation is well within the range of int values. Do we up-cast or down-cast when we manipulate only long values? Let’s see an example:

  long num1 = 20L; long num2 = 6L; long num3 = 34L; long sum = num1 + num2 + num3; System.out.println(sum);

  Result of this code is: 60 Since all the variables were of type long, there was no need to either up-cast or down-cast. What happens when you up-cast explicitly where it is not necessary? For instance, we have a result of the calculation stored in a long type and the values added are also of type long. Let’s see:

  long num1 = 20L; long num2 = 6L; long num3 = 34L; long sum = (long)((long)num1 + num2 + num3); System.out.println(sum);

  Nothing changed. It still works. But the code is redundant. There was no need at all to do casting here. This is bad programming practice. Say that loud please.

Number systems

  Now; our integer literal values come in four flavors namely: binary,

  

decimal, octal and hexadecimal. We have seen only decimal flavor as literal

  values on the examples so far. Please note that you will not be asked to convert from one number system to another in the OCA exams. You just have to be able to identify types of literal values assigned to your integer variables as they won’t always be decimal. A variable literal value could either be decimal or binary or octal or hexadecimal.

  Let’s look at each flavor individually and understand how each works. First up is decimal number system.

Decimal number system

  We have covered this number system already in all the examples I have used so far. It is a base-10 number system; meaning it uses 10 digits, numbers from 0 to 9. It has a total of ten digits. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. The number 90 is a decimal because it has digits 9 and 0. Following are examples of decimals:

  byte num1 = 20; short num2 = 6; int num3 = 34; long num4 = 5L;

Binary number system

  This number system is a base-2 number system and it uses only two digits namely: 0 and 1. A binary value can be assigned to an integer variable. For instance the decimal value 12 is equivalent to 1100 binary. Please do not worry about being asked to convert from one number system to another in the OCA exams. But it would be nice though to be able to convert from one number system to another. That part is not covered in this eBook. I am going to declare a few variables and assign literal values of type binary to them so you can see binary number system in action: int num1 = 0B0101; int num2 = 0b1001; num1 is equivalent to 5 and num2 is equivalent to 9.

  Let’s look at num1 variable: The literal value starts with 0B. This simply indicates that we are having a binary literal value. Remember a binary number system is a base-2 number system using only 0 and 1. Looking at the digits following 0B, it is either a 0 or 1. So the literal value is valid and it is a binary value.

  Let’s now look at num2 variable. The literal value starts with 0b. Letter b uses lowercase here and it also indicates that we are using a binary number system. Then the 0s and 1s follow. 0B and 0b are equivalent.

Octal number system

  Now the number system octal is a base-8 number system and it uses only 8 digits namely: 0, 1, 2, 3, 4, 5, 6, 7. How do you identify a literal value that is an octal? An octal number needs to start with value 0; not 0B as this is binary. Let’s see a few examples of octal literal values:

  int num1 = 052; int num2 = 0101; num1 is equivalent to 42 and num2 is equivalent to 65. Variable num1 has a literal value of type octal, because it starts with 0. Digits 5 and 2 are found in the octal number system. Remember octal has eight digits ranging from 0 to 7.

  Variable num2 is an octal literal value. But we said binary number system has 2 digits namely 0 and 1. Could this be a binary number? No, because binary starts with 0B or 0b. Got it?

Hexadecimal number system

  This number system is a base-16 number system which uses digits from 0 to 9 and letters A to F (total of 16 digits and letters). The numbers are as follows: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 and the letters are as follows: A, B, C, D, E,

  F. Let’s have a few examples using this number system to see it in action:

  long num1 = 0x23FA; int num2 = 0X654C; num1 is equivalent to 9210 and num2 is equivalent to 25932.

  I have declared variable num1 of type long with a literal value starting with 0x. This 0x indicates that we are having a hexadecimal literal value. Numbers 2, 3 and letters F, A are all part of the hexadecimal number system.

  I have also declared variable num2 of type int with a literal value starting with 0X. This also indicates that we are having a hexadecimal literal value. Uppercase 0X and lowercase 0x are equivalent. Either of them works.

Combined number system manipulation

  Please note that we can do some calculations using literal values of different number systems; because they are all integers at the end of the day. We would do up-casting or down-casting where necessary as we did when we were dealing with decimal number system. Let’s see an example:

  long num1 = 0x23FA; int num2 = 012; long num3 = 6; int num4 = 0B0101; long sum = num1 + num2 + num3 + num4; System.out.println(sum);

  The result of the calculation is : 9231 Let me unpack what is happening here: I have declared variable num1 of type long and stored a hexadecimal literal value. I have also declared variable num2 of type int and stored an octal literal value. I have also declared variable num3 of type long and stored a decimal literal value. I have also declared variable num4 of type int and stored a binary literal value. The variable to store result of the calculation is of type long. I have used long because, I do not want to down-cast to smaller data types. The example worked fine as all these variables have been assigned integer values, despite the fact that they represent different number systems.

Floating-point number data type

  We have been storing our literal values as integers using either of these categories: byte, short, int or long. These data types keep whole numbers; numbers without decimal places. Imagine we want to store one’s height which is 1.90 m in a variable. An integer variable cannot store this number as it has decimal places. Let’s try and put this number in an int variable.

  int height = 1.90;

  This line of code does not compile. We are not allowed to put this number into an int variable. Then what do we do if we need to have this number in a variable? Java provides us with two data types that are meant to store numbers with decimal places namely:

  ü float ü double

  A float data type has a size of 32-bits with a range of values from

  • +/–1.4E–45 to +/–3.4028235E+38, +/–infinity, +/–0, NaN and a double data

  type has a size of 64-bits with a range of values from +/–4.9E–324 to +/–1.7976931348623157E+308, +/–infinity, +/–0, NaN.

  What this means is that double data type is far bigger than the float data type in terms of size. But both data type variables store values with decimal places. Let me now focus on the float data type.

  float data type How do we differentiate between a float and double variable literal values? Let’s declare a variable of type float and see how it is done:

  float height = 1.90;

  This line of code should compile, but it does not. What is wrong here? All literal values with decimal places default to type double. So we are trying to assign a double value to a float variable. Now remember that when we assign a bigger literal value to a smaller data type; we down-cast. Let me try to do that and see if it works.

  float height = (float) 1.90;

  This line of code compiles now. But isn’t there a way to declare a variable of type float without down-casting? There must be a way, I hear you say that. You are absolutely right. How do we then declare a float variable without down-casting? Here is how:

  float height = 1.90F;

  Is that it? Yes that is it. All I did was add F as suffix to the literal value to explicitly say; this is a float literal value. Can we add lowercase f as suffix? Let’s try it out and see.

  float height = 1.90f;

  Yes we can. Both lowercase f and uppercase F are acceptable suffixes for a float literal value. We are now going to do some addition of float values and integers and see how casting works with floats. float height = 1.90f; int width = 12; float total = height + width; System.out.println(total);

  The result of this program is: 13.9 Let me unpack what is happening here. I have declared variable height of type float and assigned 1.90F to it. I have also declared variable width of type int and initialized it to 12. I have also declared variable total of type float. This variable will store a sum of a float and int literal values. In my calculation, width; which is of type int; is promoted to a float implicitly and the total of width and height becomes a float type. It then makes sense to declare total variable to be of type float. What happens if we change our

  total variable to int type? Let us see: float height = 1.90f; int width = 12; int total = height + width; System.out.println(total);

  The code does not compile. Why? Our calculation of int and float literal values resulted in a float value. Now a float value cannot fit in an int variable because it has decimal places. So what do we do? We have to tell the compiler that we want to explicitly down-cast to int type.

  Let’s see: float height = 1.90f; int width = 12; int total = (int) (height + width); System.out.println(total);

  The code now compiles and the result is 13, not 13.90. So when we down- cast from float to int, decimal places were lost. As much as down-casting is allowed, please be sure that the result you are getting is the intended one.

  double data type

  A double data type is bigger in terms of size than a float type. To declare a variable to be of type double; we simple use double keyword and then assign the literal value as follows:

  double salary = 12.09;

  I have declared a variable salary of type double and assigned 12.09 to it. You can also add suffix d or D to the literal value to explicitly say; this is a double literal value. Let us see the example:

  double salary = 12.09D; or double salary = 12.09d;

  This suffix is not necessary, as the value is a double already. How about this line of code? Will it compile? If yes, can you explain why?

  double salary = 12.09F;

  The line of code compiles. We have stored a float literal value in a double variable. Remember a double is bigger than a float; hence there is no compile error here. Let’s see if we can store the result of a calculation that involves a double and a float in a float variable. Here is the example:

  double salary = 12.09; float tax = 3.0F; float netPay = salary - tax; System.out.println(netPay);

  We have a compile error here, because we are converting a double; which is the result of addition; to a float. We need to down-cast here in order for this code to work. Let’s see how we correct this code:

  double salary = 12.09; float tax = 3.0F; float netPay = (float) (salary - tax); System.out.println(netPay);

  The code now compiles because, we have told the compiler explicitly that we were down-casting to float and the result of this program is: 9.09

  boolean data type

  A boolean data type can hold one of the two values only namely: true or

  false. We use booleans to test a condition. For instance; are you enjoying

  java? This question expects a yes or no answer. Your yes represents boolean

  

true and your no represents boolean false. Please note that boolean is a java

  keyword. Let me have a few examples where I declare variables of type boolean.

  boolean areYouUnderAge = false; boolean didYouPassExams = true;

  I have created two variables of type boolean and initialized one to false and the other to true. If you notice my variable names, you will notice that they are asking a question. That is exactly the condition that I am checking. We basically use boolean variables in conjunction with the if statement. For example:

  boolean areYouUnderAge = false; if(areYouUnderAge == true){ System.out.println("I am under age."); }else{ System.out.println("I am not under age."); }

  Here I conducted a check to see if you are under age. Our variable which we use to check was initialized to false. So our test does not meet the condition when we test with true literal value. Then the else part of the if statement gets executed and we get our result as follows: I am not under age.

  Here is another example using a boolean literal value:

  boolean didYouPassExams = true; if(didYouPassExams == true){ System.out.println("I passed my exams."); }else{ System.out.println("I did not pass my exams."); }

  When I test my variable against a true literal value, the condition becomes true because didYouPassExams variable was initialized to true. Our output is as follows from running this code: I passed my exams.

  Please note that we cannot do casting with boolean data type. Neither can we do up-casting nor can we do down-casting. It just doesn’t work with booleans.

  Introduction of underscores in our literal values

  Java 7 introduced usage of underscores in numeric literal values for readability purposes. For instance; we can add underscores in our numeric literal values as part of the number. Internally, the underscores are removed and the number is processed normally. Underscores are meant for programmers to make sense of the numbers they are using. Let’s look at a few examples where we use underscores in our numbers to see how this works:

  byte num1 = 10_9; short num2 = 13_4; int num3 = 2_3; float num4 = 1_2.3F; double num5 = 345.8_7; System.out.println(num1 + " : " + num2 + " : " + num3 + " : " + num4 + " : " + num5);

  The result of this code is:

  109 : 134 : 23 : 12.3 : 345.87

  Let me explain what is happening here: I declared a byte variable num1 and assigned 109 to it. But I decided to separate the number using an underscore. This number might mean this to me: 10 is the month; 9 is the date. But when it is printed, it is still interpreted as 109. The same goes for short, int, float and double literal values. The underscores do not have any effect on the number. We have so far used decimal number system literal values in our example. Let’s try and use literal values from other number systems. int num1 = 01_25; int num2 = 0B10_11; int num3 = 0X12A_F; System.out.println(num1 + " : " + num2 + " : " + num3 );

  The result of this code is:

  85 : 11 : 4783

  Let me unpack what is happening here. I declared a variable num1 and assigned 0125 to it. This literal value starts with 0 and the numbers in it are between the numbers from 0 to 7, so it is safe to say it is an octal literal value. I then declared variable num2 which stores a binary literal value. It is binary, because the literal value starts with 0B and 0s and 1s follow and they are the specified digits we can have for a binary literal value. I then declared variable

  

num3 which stores a hexadecimal literal value. It is hexadecimal, because the

value starts with 0X and the subsequent values are between 0 - 9 and A - F.

  Can I put the underscore anywhere in a numeric literal value? No. There are rules to follow; failing which your code won’t compile.

  You cannot put an underscore prior to or after the L or l suffix on a literal value of type long. Such code won’t compile. Let’s see an example of code that won’t compile:

  long num1 = 127.09_L; long num2 = 127.09L_;

  You cannot start or end a literal value with an underscore. Such code won’t compile. Let’s see an example of code that won’t compile:

  int num1 = 127_; int num2 = _127;

  You can place an underscore immediately after the prefix 0 in an octal literal value. Such code would compile Let’s see an example of code that will compile:

  int num1 = 0_245;

  You cannot have an underscore immediately after 0b, 0B and 0x, 0X that we use for binary and hexadecimal literal values respectively. Such code won’t compile. Let’s see an example of code that won’t compile:

  int num1 = 0_B1001; int num2 = 0X_1001;

  You cannot place an underscore prior to f, F or d, D suffix for float and double literal values. Such code would not compile. Let’s see examples of code that won’t compile:

  float num1 = 12.90_f; float num2 = 12.90_F; double num3 = 12.90_D; double num4 = 12.90_d; You cannot put an underscore adjacent to the decimal point; that is the dot. Such code would not compile. Let’s see example of code that won’t compile:

  float num2 = 12_.90F; double num3 = 12._90;

Identifiers

  Identifiers are the names we give to packages, variables, classes, interfaces and methods. An identifier is user-defined. We declare them ourselves as programmers. For instance;

  int age = 10;

  The name age is user-defined and it is referred to as an identifier. One more example of an identifier is:

  double salary = 3098.90;

  The name salary is referred to as an identifier. Please make sure that your identifier names are descriptive of what they hold or do. Imagine an identifier that will hold one’s age and you name it as name. For instance;

  int name = 7; The code is correct and it compiles, but it is so confusing and misleading.

  Another example of a misleading identifier is as follows:

  char salary = 'c';

  I am sure you can now see the importance of having descriptive names for your identifiers. Let’s see an example of good identifier names:

  int age = 10; char letter = 'c'; double salary = 340.00; String name = "Marks";

  Please note that if your identifier name is built from a combination of words; you need to capitalize the first letter of each word. Variables should be made lowercase and simply capitalize the first letter of each word from the second word as in these examples:

  double januarySalary = 9000.00; String youngestSisterName = "Grace"; float marksHeight = 1.90F; Identifier rules

  There are rules that control how we declare identifiers. These rules make sure that our identifiers are acceptable to the compiler. This though does not necessarily mean our identifier names that we come up with are descriptive of what they do. Getting descriptive identifier names is a skill that you need to master if other programmers have to work on your code and understand it. Here are the rules for valid identifiers:

  An identifier name should start with a letter a-z (uppercase or lowercase) or an underscore or a currency sign. Let’s look at examples of valid identifier names applying this rule.

  int age; int Height; float _salary; double $wages;

  These identifier names meet this rule. First identifier name starts with a lowercase letter. Second identifier name starts with an uppercase letter. Third identifier name starts with an underscore. Fourth identifier name starts with a currency sign. This sign could be a Yen, Pound, or any sign as long it is a currency of a country. If your identifier name starts with any other thing except these; that is underscore, currency sign or a letter; your code won’t compile.

  You can have a digit or digits as part of your identifier name as long as it is not at the starting position of your identifier name. For instance; this line of code is valid:

  int marks90 = 90;

  The following line code is invalid because it starts with a number and it won’t compile:

  int 12age = 12;

  You can have an underscore anywhere in your identifier name. For example; this identifier name is valid: double _sala_ry_ = 39.90;

  You can have a currency sign anywhere in your identifier name. For example; this identifier name is valid:

  double w$ages£ = 19.87;

  You cannot use a java keyword as your identifier. Let’s see a few examples where java keywords are used as identifier names and the code fails to compile:

  double break = 90.0; int continue = 78; String while = "Oops";

  All these identifier names are java keywords and they are not allowed to be used as identifiers.

Differences between object reference and primitive values Exam Objective 7

  I’ll first delve deeper into object reference variables as we have seen primitive variables already. An object reference variable is a complex type, unlike primitive variables which are considered a simple type. A primitive variable; after declaration; has itself and its contents stored in a memory call stack memory. An object reference variable does not store any of its data in the stack memory. In the stack memory, the object reference variable stores the address of the object it is pointing to. The object with the actual data is stored in a memory called heap memory. Let’s simplify this by having a graphical illustration in order for us to fully comprehend this concept:

  intage à 10 (Stack memory)

Car smallCar à CETSAU90 à Car Object( Red, Porsche, 260) – (Heap

memory)