File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Compiler vs. Runtime Errors Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Compiler vs. Runtime Errors" Watch "Compiler vs. Runtime Errors" New topic

Compiler vs. Runtime Errors

Michael Scott
Ranch Hand

Joined: Jan 20, 2003
Posts: 57
I'm preparing to take the Sun Programmer exam. In the practice exams, many of the questions present Java code and ask whether or not compiling and running it will result in a 'compiler error' or 'runtime' error. I'm interested in whether anyone could recommend any good documentation that summarizes the typical scenarios under which compiler and runtime errors occur.
Jasper Vader
Ranch Hand

Joined: Jan 10, 2003
Posts: 284
Yeah, like a little checklist or something
I might comment that checked exceptions are 'checked' at compilation time, and unchecked exceptions are not and may cause a runtime exception if they happen.

giddee up
Kathy Sierra
Cowgirl and Author

Joined: Oct 10, 2002
Posts: 1589
Hmmmm.... I don't have a list, but I have a few comments off the top of my head. But first, a disclaimer -- by the time you are ready for the exam, the issue of which things are runtime vs. compiler problems will probably be clear to you.
But for now, I can offer a few things to think about;
1) The compiler cares deeply about TYPE. If the compiler has enough information to KNOW that you have a type problem, it (the compiler) will complain. And by type I mean reference or primitive type.
Dog d = new Dog(); // no problem
Animal a = new Dog(); // no problem if Dog extends Animal
Dog d = new Animal(); // COMPILER ERROR! The compiler knows that since Dog extends Animal, *not all Animals are Dogs*.
Dog d = new Cat(); // COMPILER ERROR! Duh.
Animal c = new Cat(); // OK, Cat extends Animal
Dog d = c; // COMPILER ERROR! But not because the compiler knows it's a Cat. The compiler sees only the REFERENCE type (Animal) and complains.
You can make the code above succeed at compiler time by using a cast, which tells the compiler, "Trust me, I know this will work at runtime. It really will be a DOG at the other end of the 'c' reference." as follows:
Dog d = (Dog) c; // OK to compiler. Compiler trusts you now. (even though you are lying)
But... since it really is NOT a Dog object (it is a Cat), the code above will produce a runtime error when the JVM realizes that it is NOT a Dog object after all, but a Cat lurking behind the reference named 'c'.
The compiler uses the REFERENCE type (not the OBJECT type) to decide if you can invoke a method. If you invoke a method on a reference type that does not HAVE that method, the compiler complains.
Cat c = new Cat();
c.bark(); // compiler error! Cats don't bark (which means there is no bark() method defined in class Cat)
Animal d = new Dog(); // OK at compile time.
d.bark(); // COMPILER ERROR
Even though you know and I know that it really IS a Dog at the end of 'd', and that Dog does have a bark() method, the compiler sees only that 'd' is of type ANIMAL, and since Animal does not have a bark() method, the compiler will not let you try. To invoke the bark() method, you would have to use a cast:
Dog doggie = (Dog) d; // OK
doggie.bark(); // OK

2) In addition to reference types, the compiler cares also about *primitive* types, in much the same way. If it KNOWS something won't fit into the declared variable type, it will complain.
float f = 23.4; // compiler sees the literal as a double, and knows a double can't fit into a float-sized variable, without a cast.
The rules above for casting primitive and reference types applies to declarations and assignments, as well as return values and arguments. If the return value is declared as type Dog, the compiler won't let you return an object referenced with an Animal reference variable type. Even it really IS a Dog... (without a cast)
public Dog foo() {
return new Animal(); // COMPILER ERROR
But this is OK at compile time:
public Dog foo() {
Animal a = new Cat();
return (Dog) a; // compiler trusts you, even though you are lying by indicating that 'a' is a Dog.
But the code above will blow up at RUNTIME when the JVM once again discovers a Cat object is at the end of the 'a' reference, and a Cat absolutely can NOT be treated as a Dog. (boy do I know that in *my* house
3) The compiler cares, of course, about syntax errors -- so anything that's missing a semicolon or a curly brace or uses parens instead of brackets for arrays, etc. will cause a compiler error.
4) The compiler cares about checked exceptions, as Jasper mentioned, so it will always be sure that you have followed the "handle or declare" rule by either providing an appropriate catch block, or by declaring the exception.
5) The compiler cares deeply about access levels, so if you try to invoke a private method of another class, the compiler will complain. (Or a default access method in a class from another package, etc.)
6) The compiler cares deeply about matching arguments to parameters, so you cannot invoke a method without sending it the arguments it is expecting.
You cannot call:
x. doStuff(); // no args
If the method is defined:
public void doStuff(int i); // defined with an int parameter
Same goes for constructors.
7) Compiler cares about implementation rules! An interface is a contract. A superclass definition is a contract. If you SAY that you implement an interface (class Foo implements Runnable), the compiler will force you to fulfill the contract by implementing the run() method defined by Runnable interface.
Same goes for abstract classes. If you extend an abstract class with a non-abstract class, the non-abstract class MUST implement all non-abstract methods of the abstract class (including abstract methods defined by any superclasses of the abstract class). The compiler can tell, so the compiler will keep you honest.
Same goes for rules of overriding. If you extend a class and override a method, the compiler KNOWS what you can and cannot do. For example, you CAN make the access level *less* restrictive (from protected to public, for example) and you CAN throw fewer or narrower (or no) checked exceptions. But you cannot do the opposite of those. And you cannot vary the return type or argument list.
The compiler also knows the rules for overloading, so it can tell if you vary JUST the return type of a method (which is illegal, of course, since you must vary the argument list in order to legally overload a method).
There are lots more, but these are the first that come to mind. I would think strongly about these things:
*The compiler cares about the 'contract' you agree to, and wants to keep you doing what you said you would do. This includes rules for checked exception handling, interface implementation, method overriding, and implementing abstract methods.
* The compiler cares about TYPE. Both object and reference type, although there are several places where the compiler cares only about the reference type (rather than the object type, since the compiler often does not know what the actual object is out there on the heap).
Again, after saying all this, by the time you have learned everything you need to pass the exam, you will understand enough to be able to know which are compiler and which are runtime errors. It is very difficult -- actually impossible -- to determine which are compiler errors and which are runtime errors just by trying to memorize a list. You must understand what the compiler is trying to do for you, and why it matters in Java, so that you can answer questions on the exam that may involve scenarios you have never seen before.
(it gets easier. it really does.)
Aaron Anders
Ranch Hand

Joined: Dec 30, 2002
Posts: 39
may i summarize the rules on casting...
- upcasting doesn't need explicit cast
- casting from one parent to other parent needs explicit cast
- downcasting needs explicit cast, but may result in runtime error
- casting to sibling is illegal
[ January 21, 2003: Message edited by: Aaron Anders ]
Jasper Vader
Ranch Hand

Joined: Jan 10, 2003
Posts: 284
thanks all for responses so far.
Kathy, that is a lot of valuable information there. As you say, memorising a list does not suffice for actual knowledge about how the compiler and JVM deal with things, and how things react... but some outlines do good things for my process.
[ January 21, 2003: Message edited by: Jasper Vader ]
Michael Scott
Ranch Hand

Joined: Jan 20, 2003
Posts: 57
I can't thank you enough for taking the time to provide such a comprehensive outline. You are truly remarkable!!! I'm still a relative newcomer to Java although I've accumulated a number of books on the subject and haven't found a single one that explains the differences between compiler and runtime errors as well as you have. I was about to suggest that you consider getting into publishing and then saw that your book "Head First Java" will be coming out. I'll certainly keep on eye out for it.
Thanks again.
Shiva Mantri

Joined: Dec 30, 2002
Posts: 19
i found this while grazing on the ranch
[ January 22, 2003: Message edited by: Shiva Mantri ]
Michael Scott
Ranch Hand

Joined: Jan 20, 2003
Posts: 57
Thanks very much for the link. It's very informative.
Jasper Vader
Ranch Hand

Joined: Jan 10, 2003
Posts: 284
Kathy,thanks again for the very cool list of things to think about . just one thing - not wishing to be a nitpicker, but i just wanted to confirm a typo?
"...extend an abstract class with a non-abstract class, the non-abstract class MUST implement all non-abstract methods of the abstract class (including abstract methods defined by any superclasses of the abstract class). "
i think that bit might have meant to be : the non-abstract class MUST implement all abstract methods of the abstract class.
As i assume it would not have to implement any non-abstract classes. (just checking, as there are so many tricks with java i dont assume anything).
I agree. Here's the link:
subject: Compiler vs. Runtime Errors
It's not a secret anymore!