Let's summarize what we learned from the last section's exercises:
Java doesn't require whitespace. We could've written our hello world program like so:
class PrintHelloWorld { public static void main(String[] args) { System.out.println("Hello world!"); } }
But don't actually do this. Indent like you would in Python; it makes your code much easier to read.
.java
files need at least one class in them. The filename must be exactly the same as the class name, capitalization included.
The main
method is a special method that must be declared exactly like this: public static void main(String[] args)
.
Every Java program (which can be made of one or more .java
files, just as a Python program might have multiple .py
files) must have exactly one main
.
Also, Java programs always start execution from the main
method.
In the last section's exercises, you got acquainted with some error messages. Now, let's break down their structure. It's important to be comfortable reading error messages because they're crucial for debugging.
In general, an error message looks like this:
Filename.java:line number: Possible cause
Print out of the error messages or the line Java thinks is wrong
Let's look at a simple error output.
$ javac Test.java
Test.java:3: ';' expected
System.out.println("hello")
^
1 error
The first line tells us what file the error is in, followed by the line number. So the error is in Test.java
at line 3. Below that, Java describes what it thinks the error is, which can often be completely wrong. In this case, Java is correct; I was missing a semicolon after the print statement.
Let's look at another one:
Test.java:3: unclosed string literal
System.out.println("hello);
^
Test.java:3: ';' expected
System.out.println("hello);
^
Test.java:5: reached end of file while parsing
}
^
3 errors
Errors can sometimes multiply. I forgot the closing quotation mark to "hello
, which caused Java to miss the semicolon at the end of the line and the closing bracket for main
. Java is seeing three errors when there is only one.
The lesson here is to always start with the first error. Once I added the closing "
to "hello
, all of the other errors went away, too.
The above errors were caught while compiling, i.e. after I ran the javac
command. But once you fix any compiler errors, there's still no guarantee your program will actually run - the compiler can only catch very basic errors.
For example, you saw in the previous exercises that if we forget the static
keyword in main's declaration, our program will compile correctly but fail at runtime:
$ javac Test.java // compiles just file
$ java Test
Exception in thread "main" java.lang.NoSuchMethodError: main // oops!
And as also saw previously, if we name our class something different than the filename, we get this runtime monstrosity:
$ javac Test.java // compiles just fine
$ java Test
Exception in thread "main" java.lang.NoClassDefFoundError: Test (wrong name: test)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:637)
at java.lang.ClassLoader.defineClass(ClassLoader.java:621)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
All of the error lines after the first are simply tracing the error through the JVM. We can safely ignore those and only look at the first line, which tells us that the error was a NoClassDefFoundError
and that Java thinks our class was given the wrong name. In this case, my class was named test
but the filename was Test.java
.
In sum, error messages can sometimes be very confusing. But if you slow down, take a deep breath, and start from the top, usually you can make sense of what's going on. The more comfortable you are with Java's vocabulary of errors and exceptions, the better you'll be at debugging.
Exceptions are problems that your program can probably handle without crashing. For example, if we try to open a file that doesn't exist, we'll get a FileNotFoundException
. Instead of crashing, our program could catch this exception, print out something like "File not found", and then exit gracefully.
Errors are serious problems that your program probably isn't going to recover from. For example, if you get an OutOfMemoryError
, your program is just going to crash and there's really nothing you can do about it.
In this course, I'll use the terms "error" and "exception" interchangably.
A majority of programming time is usually spent debugging, so the faster you can debug, the faster you'll be able to program. The first two exercises will give you more practice with error messages and the final two with printing.
Even if you see what the bugs are right away, don't fix them without compiling. Fix one error at a time and compile after every change so you can actually get used to the error outputs.
Go through this very broken program and fix the bugs. Remember to name your file exactly the same as the class. (Hint: it may be helpful to reformat the code with correct indentation).
/ This code totally won't work.
System.out.println("I'm a print statement."); class PrettyTerrible {
System.out.println('Woo hoo, I'm printing stuff!'); public static main(Stirng[] args) {
print("Hello world!");
System.out.println("Hey, I want to say hello too!")System.out.println("Me too!); }
Fix the bugs in this program, too:
// This is slightly less broken, but still bad
class LessBad() {
public statc void main string args {
System.out.print("Hello ");
System.out.println(" world!") }
} }
Print out the numbers 1 through 5 on separate lines, like this:
1
2
3
4
5
Can you do this using only one print statement? (Hint: remember \n
?) Google how to do this if you get stuck, but don't worry if you can't figure it out.
Print out the numbers 1 through 5 on the same line, like this:
1 2 3 4 5
Can you do this using 5 different print statements? (Remember to use Google).