RastcodeS

Where we take good care of both your front and back-end needs

Great place to take your code to the next level

Checkout my work and get in touch



RastcodeS Logo
Go Back

Java Break - Primitives vs References - Java Core Part - V


Java



Written by Rastko

date - 09/Sep/18 | views - 227

Java Break - Primitives vs References - Java Core Part - V

     Introduction to Java Primitives and Object References. Differences between the types explained.

     The fifth part in the Java Break series, where we explore the core features of Java language. Check out the previous chapters:

 

     In Java programs, you can expect to find two different types data - primitive types and reference types. Both groups have many subtypes and in the case of object references, sky is the limit. We'll try to explain the main differences between the two major groups, so let's begin.

 

Primitive Types

 

     There are 8 built-in Java primitive types. Even though it might seem strange, these are the core parts of every Java object. That means each object can, at some point, get deduced to primitive types.

     Let's take a look at a useful table, which will help us understand how these primitives work. We have a keyword representing the type, it's size and an example.

Type Size Example
boolean 2 values - true or false true
byte 8 bit integral 88
short 16 bit integral 88
int 32 bit integral 88
long 64 bit integral 88
float 32 bit floating point 88.88f
double 64 bit floating point 88.88
char 16 bit Unicode 'a'
 

     Ok, a lot of things  are going on here. Let's try to explain it, but keep the table as a reference.

     As you can see, on one hand we have integral and on the other floating point numeric values. Integral values (byte, short, int and long) represent whole numbers. Floating point types (float and double) are for the decimal values.

     The numeric values have another simple rule. Each integral type uses twice as many bits as the previous one. The same goes for the floating point types.  Also, the float type, requires an f at the end.

     You don't need to learn the primitive sizes by heart, but it's good to know, which is larger than the other. Still, let's cover how we calculate these maximum and minimum values. We'll explain this on the byte example. Byte holds 8 bits and each bit has two possible values. So, 2 x 2 x 2 x 2 x 2 x 2 x 2 x 2 = 4 x 4 x 4 x 4 = 16 x 16 = 256. So a byte can hold a value between -128 to 127. What happened to 128? Don't forget the 0. Short as a 16 bit integral value can be anywhere form  -32,768 to 32,767. Int - from  -2,147,483,648 to 2,147,483,648. Long - from -9,223,372,036,854,775,808  to 9,223,372,036,854,775,807. That's a huge number.

     If you write something like this:

int largeNumber;

 

     The simple code above tells Java to allocate 32 bits in memory for it. There are a few extra rules, you should know about. If you have a number in your code, that number is considered a literal. When you use a literal, java will assume your defining an int type. Here's the problem:

int hugeNumber = 3456789012;

 

     This code will not compile as this larger than int can hold. You might think we can fix it by assigning the number to a long:

long hugeNumber = 3456789012;

 

     No, this doesn't compile either. It believes the hugeNumber is out of range. It actually is, as Java again assumes it's an int. To fix it, we need to specify we want to use a long, by adding L to the end:

int hugeNumber = 3456789012L;

 

     Now the code compiles. You can also add a lowercase l, but it is considered bad practice, as it can be confused for number 1.

     To finish up this first part let's discuss a feature introduced in Java 7. That's the ability to add underscores to numbers, so they are easier to read:

int largeNumber = 999999999;
int sameNumber = 999_999_999;

 

     They represent the same number, but the second one is easier to read. You can do the same thing for a floating point type:

double floatingNumber = 1_000.23_54;

 

     The floatingNumber is OK. However, there are some rules when adding underscores to literals.

You are not allowed to place an underscore to the beginning:

double beginning = _555.55;

 

You are not allowed to place an underscore at the end:

double end = 555.55_;

 

You are not allowed to place an underscore before a decimal point:

double beforeDecimal = 555_.55;

 

You are not allowed to place an underscore after a decimal point:

double afterDecimal = 555._55;

 

     Non of those would compile, so keep an eye on them.


 

Reference Types

 

     We've already pointed out there's an endless number of reference types. As the name implies, reference types refer to an object, which is a instance of a class. Important thing to know is that references do not actually hold the value. Instead, they hold a memory address, which points to the object. This concept, we call a pointer. Some other programming languages will let you get a hold of this address and then directly access an object. This is not the case with Java. You can only access an object through a reference. Let's take a look at a simple example:

String name = "John";

 

     We always start with the data type, in our case String. Then comes the reference variable - name. This reference can only point to a String object, so this wouldn't work:

String name = "John";
name = new Date();

 

     So there are a couple of rules.

We can assign a reference to another object of the same type:

String name = "John";
name = "Bob";

 

We can assign a reference can to a new object, using the new keyword:

Date date = new Date();

 

     You might be wandering, why haven't we used the new keyword when assigning "John" to name. Strings are exceptions and we'll cover everything you need to know about them in one of the later chapters. Still, you should know that both of these are legal:

String name = "John";
String anotherName = new String("Bob");

 

     To further explain reference types, let's go back to the Person class, we've created in the previous article:

public class Person {
   
   int age;
   String name;
  
   public Person(int age, String name) {
      this.age = age;
      this.name = name;
   }

   public static void main(String[] args) {
      Person man = new Person(30, "John");
      Person woman = new Person(27, "Julia");
      Person anotherWoman = new Person(45, "Mary");

      man.name = "Mike";
      System.out.println(man.name);
      
      man = new Person(31, "Bob");
      System.out.println(man.name);

      woman = anotherWoman;
      System.out.println(woman.name);
   }
}

 

     Person is our class. Inside the main method, we first declare a reference - man, pointing to a Person object. On the right hand side we declare that this is a new Person object. Though the constructor, we assign initial vaules. We do the same with the woman and anotherWoman references. Next, we change the name of the Person object with the man reference. It is still the same object. The print statement outputs Mike. However, on the next line we declare that the man reference now points to a new object with a name of "Bob". There are no more references to the initial Person object and Java might try to garbage-collect it. We'll discuss garbage collection in one of the next vaules. The last line declares the woman reference now points to the Person object, initially referenced by anotherWoman. The second Person object, now also has no references pointing to it and can be garbage-collected.


 

Main Differences between Primitives and Reference Types

 

     Reference and Primitive types have many differences, but we have 3 important ones.

     A reference type can be assigned to null. This means that this reference type doesn't point to an object:

String name = null;

 

     On the other hand, primitives ca not be null and trying to assign them to null will give you a compiler error:

int age = null;

 

     If a reference type is not null, it can be used to call methods:

String name = "John"
int nameLength = name.length();

 

     The length method returns the number of character in a given String. Primitives do not have any methods declared, so they can't call any methods.

     The last main difference, which you might have noticed, is in the naming. All primitives have lowercase names - int, double, long... All reference types, on the other hand, begin with an uppercase letter - String, Date, even our Person type.

 

     That's all for this chapter. In the next Java Break, we'll discuss variable declaration and initialization.  See you then.

 


View Post/Backend
Login to comment

Comments


No Comments yet. Be the first!

Currently working on a Laravel project

Check it out
Java Break - Declare and Initialize Variables - Java Core Part - VI
Java Break - Declare and Initialize Variables - Java Core Part - VI

     Declaring and initializing variable in Java. How to do it properly and avoid mistakes.

     The sixth chapter...

Java


Recents


Popular