a macbook sits on a desk surrounded by black and white plans for a house
Loosely related image from pexels.com to make this post look nicer in social media shares.

Let’s talk about classes! Classes in Java are super weird (okay they’re weird in any language), and I really struggled with them when I was learning Java, so don’t feel bad if classes/objects are hard for you.

When you write simple code where everything is in main and runs immediately, it’s way easier. With classes you can’t just write it and call it, you have to create an instance first. What’s even going on there?

A class in Java is just a blueprint, it doesn’t do anything until you create an object using the blueprint (there are exceptions but let’s go with that for now). That’s a big part of the weirdness, you write all this code and it just kinda sits there until you write even more code, and here’s the kicker: that code has to be somewhere else.

In a small project your probably have a Main class somewhere that has a main() method, that’s where you need to call your other class from. Why? Because Java says so, that’s why :) Or more precisely, when you run a Java project you have to tell the JVM where to start. Something, somewhere, has to have a main method no matter how you run your project. Even if you create an archive that you drop into a servlet container like Tomcat or Jetty, that servlet container has a main method somewhere that gets called when you start it up. It may be very stealthily called by a script that calls a script that starts a service, but there’s definitely a main method in there somewhere. No matter how complicated an application seems, it’s really just a much larger version of the tiny little projects you do in school. Programs get larger and larger but the basic principles always stay the same.

Back at basic principles, you create actual objects you can interact with using the class/blueprint. In Java you do that with the new keyword. new YourClassName() creates an object using the blueprint, you can assign that to a variable like any other value and then do what you like with it. Once you create an object it’s separate from any other object you create even if you use the same blueprint (class) again. Again, there are exceptions, but I’m trying to keep this simple.

It’s like building two houses from the same set of plans, they’re separate houses even if they start out the same. You can put completely different furniture in each of them, paint them different colours, make a bedroom into a home office, but whatever you do to one house doesn’t affect the other one. And you can put objects inside other objects, like a house object could contain a fridge object or a couch object or a CNC router object if you have an especially interesting garage.

You could also have an array of house objects – pretend you’re keeping track of one of those subdivisions where all the houses are the same :) Those houses could have a method like closeWindows (pretend it’s an automated house), so you could loop through your array of suspiciously similar houses and close all the windows if the weather report said it was likely to rain. But you would need to call the closeWindows method on every single house, if you close the windows of one house it doesn’t affect the others.

This gets much more complicated when you start thinking about multithreading, static methods, and static fields, but those are another blog post. For now all I want to get at is that Java needs you to spell out exactly where to start and that programs all work pretty much the same way no matter how complicated they are. Frameworks like Spring or Struts and containers like Tomcat and Jetty will hide details from you, but no matter how many other programs or libraries you use, the computer always needs to know where to start.