Hello again! At this point we’ve covered bits, primitive types, various operators, and variable creation in Java. In this lesson, we’re going to kick off a series of tutorials that tackle the core aspects of object-oriented design. In particular, we’re going to cover reference types and how they will impact you moving forward.
Table of Contents
Last time, we touched on strings because they are often associated with the primitive types. This is because they are natively supported by Java. However, strings are not a primitive type. This becomes quite clear if you try comparing two seemingly equal strings with the
With primitive types
== is valid and frankly the only reasonable way to perform the comparison (we can chat about wrappers later). However, strings are reference types which means they do not store the string value directly.
Instead, they store a reference to the string value. This means an
== comparison is actually comparing the memory addresses of those two strings. Because each string has a different address, the comparison will fail.
But I tried this in [insert IDE here] and it returned true…
Yeah, this might happen to you because of the Java Virtual Machine. The comparison returns true because the JVM optimizes the program by only storing one copy of all duplicate strings. This means the addresses will be the same for seemingly equal strings. Oracle calls this type of optimization string interning. Be aware, however, that most reference types do not behave this way and should not be compared using
Comparing Reference Types
The cool thing about reference types is that they have a whole host of additional features that primitive types do not. For strings, this means we can get information like the length of the string or determine a character at a specific location in the string. This is accomplished by using the dot operator:
String sentence = "Java strings are awesome!"; int numOfChars = sentence.length();
This dot operator triggers the length functionality for a string which we capture in a variable. This is where the replacement for
== comes in. Every reference type in Java can be compared using the following dot operator syntax:
String firstName = "Leroy"; String lastName = "Leroy"; firstName.equals(lastName);
Using our old example, we can now compare Leroy’s first and last name with certainty that it will return true.
Introduction to Objects
We have been trying to take this material at a comfortable pace so just about anyone can pick up their first programming language. In order to do so, we have dodged some of the most critical concepts in Java.
Reference Types and Objects Are Synonymous
Perhaps the most integral part of the Java language is this notion of an object. What exactly is an object? How can we use objects? What purpose do objects serve? These are the types of questions that we will be addressing with every lesson moving forward.
In fact, objects are such an important part of the language that we should probably let you know that you have already been working with some. That’s right! Strings are objects.
Then why are we chatting about reference types?
Objects are synonymous with reference types in Java. In other words, you can swap ‘reference type’ with ‘object’ anywhere in this tutorial and it would still read correctly.
In fact, the only reason we introduce objects as reference types is to get the point across that objects do not store their data directly. You cannot compare objects the same way you compare primitive types because objects are referenced by a memory address. This will be crucial once we start talking about creating our own objects.
The Dot Operator
For now, let’s talk about this dot operator. When we use the dot operator on an object such as a string, we are actually doing one of two things: making a method call or accessing a field. We’ll talk more about fields later.
At any rate, a method is the object-oriented term for a function. In other words, a method performs a function.
In the first example, we called the length method on a sentence to determine the length of that sentence. However,
length() is not a method that just exists for all objects;
length() is defined specifically for strings.
If we want to know what
length() does, we have to take a look at the
String class. A class is the actual source code for an object while an object is the living form of that class.
For strings, this means that the
String class defines all the functionality like the
length() method, and the object is the actual instantiation of that class (i.e. “This is a string object”). The methods can then be called to perform some function on that particular instance of an object.
To give you an idea of what a class might entail (and to get you acclimated to the Java API), head on over to the Java 7 String documentation. Here you will see every method that strings have access to along with a description of those methods.
Don’t worry if this starts to feel overwhelming. Up next, we will be covering the basics of writing your own methods, so you can get an idea of how they work in a greater context.
Kicking off a new series of reverse engineering content inspired by VirtualFlatCAD. Today, we're trying to roll our own uppercase function.
When it comes to capitalizing strings in Python, you have a few options. Use the tools Python provides or roll your own.