-
Book Overview & Buying
-
Table Of Contents
-
Feedback & Rating

Learn Java with Projects
By :

Java was developed by James Gosling at Sun Microsystems in the mid-1990s. When Java was created, it was originally designed as a language for consumer electronics. It attempted to support complex host architectures, focused on portability, and supported secure networking. However, Java outgrew its own ambitions. It quickly gained momentum as a versatile language for creating enterprise, web, and mobile applications. Today, Java no longer belongs to Sun Microsystems. Oracle Corporation acquired Sun Microsystems in 2010. And with that acquirement, Java became an integral part of Oracle’s software ecosystem.
Java was very unique at the time it was created. The huge success of Java can be attributed to some of its core features. These features were very innovative at the time but are now found in many other (competing) languages. One of the core features is object-oriented programming. OOP allows us to structure our code in a neat way that helps with reusability and maintainability. We’re going to start discussing the core features by having a look at object-oriented programming (OOP).
Arguably the most important feature of Java is its support for OOP. If you ask any Java developer what Java is, the answer is often that it’s an OOP language.
It’s safe to say that OOP is a key feature. What is this OOP thing? you may wonder. OOP is a programming paradigm. It structures applications to model real-world objects and their interactions and behaviors. Let’s go over the main concepts of OOP:
Car
class might define attributes such as color, make, and model, and methods such as start, accelerate, and brake.Car
could inherit from a Vehicle
class. We’re not going to cover the details here, but inheritance helps to better structure the code. The code is more reusable, and the hierarchy of related classes opens doors in terms of what we can do with our types.I can imagine this all sounds very abstract at this point, but before you know it, you’ll be creating classes and instantiating objects yourself. OOP helps to make code more maintainable, better structured, and reusable. These things really help to be able to make changes to your application, solve problems, and scale up when needed.
OOP is just one key feature of Java. Another key feature is that it’s a compiled language. Let’s make sure you understand what is meant by that now.
Java is a compiled programming language, which means that the source code you write must be transformed into a machine-readable format before it can be interpreted. This machine-readable format is called bytecode. This process is different from that of interpreted languages, where the source code is read, interpreted, and executed on the fly. During runtime, the computer interprets an interpreted language line by line. When a compiled language is running, the computer interprets the bytecode during runtime. We’ll dive deeper into the compilation process in just a bit when we are going to compile our own code. For now, let’s see what the benefits of compiled languages are.
Compiling code first requires an extra step, and it takes time in the beginning, but it brings advantages. First of all, the performance of compiled languages is typically better than interpreted languages. This is because the bytecode gets optimized for efficient execution on the target platform.
Another advantage of compilation is the early detection of syntax errors and certain other types of errors before the code is executed. This enables developers to identify and fix issues before deploying the application, reducing the likelihood of runtime errors.
Java code is turned into bytecode – a form of binary code - by the compiler. This bytecode is platform-independent. This means that it allows Java applications to run on different operating systems without modification. Platform independence is actually the key feature that we’re going to be discussing next.
Java’s Write Once, Run Anywhere (WORA) principle is another key feature. This used to set Java apart from many other programming languages, but now, this is rather common, and many competing languages also implemented this feature. This principle ensures that Java code can run on different platforms without requiring different versions of the Java code for each platform. This means that a Java program is not tied to any specific operating system or hardware architecture.
When you have different versions of the code for each platform, this means that you have to maintain all these versions of the code as well. Let’s say you have a code base for Linux, macOS, and Windows. When a new feature or a change is required, you need to add this to three places! You can imagine that WORA was a game-changer at the time Java came out. And it leads to an increased reach of your application – any device that can run Java applications can run yours.
The WORA principle is made possible by bytecode and the Java Virtual Machine (JVM). Bytecode is the compiled Java program. The compiler turns the Java code into this bytecode, and this bytecode is platform-independent. It can run on any device that can run the bytecode executer.
This bytecode executer is called the JVM. Each platform (Windows, macOS, Linux, and so on) has its own JVM implementation, which is specifically designed to translate bytecode into native machine code for that platform. Since the bytecode remains the same across platforms, the JVM handles the differences between operating systems and hardware architectures. The WORA principle is explained in Figure 1.1.
Figure 1.1 – The WORA principle in a diagram
You can see that the compiler creates bytecode and that this bytecode can be picked up by the JVM. The JVM is platform-specific and does the translation to the platform it’s on. There’s more that the JVM does for us, and that is automatic memory management. Let’s explore this next.
Another key feature that made Java great is its automatic memory management, which simplifies development and prevents common memory-related errors. Java handles memory allocation and garbage collection for you. The developer doesn’t need to take care of manually managing the memory.
Nowadays, this is the rule and not the exception. Most other modern languages have automatic memory management as well. However, it is important to know what automatic memory management means. The memory allocation and deallocation are done automatically. This actually leads to simplifying the code. There is no boilerplate code that just focuses on the allocation and deallocation of the memory. This also leads to fewer memory-related errors.
Let’s make sure you understand what is meant by memory allocation and deallocation.
In code, you create variables. Sometimes, these variables are not simple values but complex objects with many data fields. When you create an object, this object needs to be stored somewhere in the memory of the device that it’s running on. This is called memory allocation. In Java, when you create an object, device memory is automatically allocated to store the object’s attributes and associated data. This is different from languages such as C and C++, where developers must manually allocate and deallocate memory. Java’s automatic memory allocation streamlines the development process and reduces the chances of memory leaks or dangling pointers, which can cause unexpected behavior or crashes. It also makes the code cleaner to read, since you don’t need to deal with any allocation or deallocation code.
When a memory block is no longer used by the application, it needs to be deallocated. The process Java uses for this is called garbage collection. Garbage collection is the process of identifying and reclaiming memory that is no longer in use by a program. In Java, when an object is no longer accessible or needed, the garbage collector automatically frees up the memory occupied by the object. This process ensures that the memory is efficiently utilized and prevents memory leaks and the problems that come with it.
The JVM periodically runs the garbage collector to identify and clean up unreachable objects. Java’s garbage collection mechanism uses many different sophisticated algorithms to determine when an object is no longer needed.
Now that we’ve covered the basics, let’s move on to installing Java.