Compiler Warnings and Errors
A Java annotation is a modifier with no direct effect on the program it annotates; its value comes from what a compiler can check against it.
Try it: Inheritance and Method Lookup
How a subclass inherits from its parent, how Python finds an attribute by walking the instance, then the class's method resolution order up to object, how overriding and super() work, why the same call does different things on different objects (polymorphism), and what isinstance / issubclass check.
How it works
- class Dog(Animal) gives Dog the MRO Dog → Animal → object; Puppy(Dog) gives Puppy → Dog → Animal → object.
- obj.name searches obj.__dict__, then each class of type(obj).__mro__ in order; the first class that defines the name wins, so a subclass method overrides the parent's.
- super().method() starts the search in the class after the one the current method was defined in, e.g. to run the parent's __init__.
- Calling the same method on a list of different objects runs each object's own version (polymorphism).
- isinstance(obj, C) is True when C is in type(obj).__mro__; if no class has the name, Python raises AttributeError.
Default run (63 steps): Ready: Animal, Dog, Cat and Puppy, then the statements you picked. Each attribute is searched along the class's MRO. … Finished. Printed: Rex the dog says Woof / Tom the cat says Meow / Bo the dog says Woof! / True / Puppy / Dog / Animal / object.
Simplified: The lab's own small Python interpreter runs a fixed, hand-written script (you choose the variant and the values, never the code); nothing is executed as real Python. Every script was run in CPython 3.12 with the same inputs and the lab reproduces its output and error messages. Single inheritance only (the lab's MRO code is Python's C3 algorithm, but no class here has two parents).
Loading the simulation…
Why Annotations Look Like Switches
Many learners first meet Java annotations as small labels that seem to switch something on in a program, much like a setting. Under that picture, writing an annotation on a method would make the method behave differently. This article tests that belief against what the language and its standard annotations actually do. The short version is that the belief is wrong, but the reason it is wrong is useful, because it shows exactly where the real value of an annotation lies.
What do you think happens?
If you place @Override in front of a method, does the method compute something different when the program runs?
Reveal answer
No, the annotation has no direct effect on the program it annotates.
The defining property of an annotation is that it has no direct effect on the program it annotates. Adding one does not alter what the code computes or how it executes on its own. Its value comes from what a compiler can check against it.
Annotations as a Channel to the Compiler
An annotation records intent. Some annotations exist to make the programmer's intention more explicit, and a compiler can check the code against that stated intention. If the code does not match what the annotation promises, the compiler can inform the programmer. This is why annotations are best understood as a channel between the programmer and the compiler rather than as switches inside the running program.
The value of an annotation lies in the checking, and the checking happens before the program runs. A mistake caught at compile time is a warning you receive in advance, rather than a bug you must later track down through testing and debugging. Keep this in mind as we trace the three standard annotations: each one either asks the compiler to verify something, flags something for the programmer, or turns a warning off.
Tracing How @Override Is Checked
The @Override annotation is placed directly in front of a method definition. It states that the method is intended to override, meaning replace, a method with the same signature defined in some superclass. The annotation is a claim, and the compiler is the party that verifies it. The compiler looks for a superclass method that matches. If one exists, the declaration is accepted. If none exists, the compiler has a concrete fault to report.
- Animal is the superclass and defines speak with no parameters
- Dog is the subclass; @Override sits directly in front of its speak method
- The compiler checks that Animal has a matching speak method, which it does, so the declaration is accepted
Read the flowchart as a trace. The compiler starts from the annotated subclass method and asks one question: does a method with the same signature exist in a superclass? Only the yes branch leads to an accepted declaration. The no branch leads to the error. Without the annotation, that second branch never runs at all, because the compiler has nothing it was asked to verify. The annotation is what creates the possibility of an error here, and it is also what gives the compiler a specific fault to point at.
Matching and Non-Matching Signatures
The check depends entirely on whether the subclass method has the same signature as a superclass method. A small detail can break the match, such as a parameter type that differs or a capitalization change in the name. Because the compiler compares against the superclass declaration, the subclass method no longer corresponds to anything it can replace, and the claim made by @Override cannot be verified.
| Subclass method | Superclass has a matching method? | Compiler outcome |
|---|---|---|
| Same name and parameters as the superclass method | Yes | Declaration accepted |
| Name differs in capitalization, such as speak versus Speak | No | Compiler error for @Override |
| A parameter type differs from the superclass method | No | Compiler error for @Override |
| Same declaration but no @Override annotation | Not checked | No error reported for the mismatch |
How the compiler responds to matching and non-matching signatures when @Override is present
Marking Obsolete Items with @Deprecated
The @Deprecated annotation marks a class, method, or variable as deprecated. A deprecated item is one considered obsolete, but which remains part of the Java language so that old code keeps working. The annotation is a way of communicating that status to anyone using the item.
Marking an item as deprecated allows a compiler to generate warnings whenever that item is used. The item still functions, so the warning is a signal to the programmer rather than a rejection of the code. Without @Deprecated on an item, the compiler has no basis for a deprecation warning. With it, the compiler can point out each use of that item. The annotation therefore moves a piece of knowledge, that this item is obsolete, from the author's head into a form the compiler can act on.
The Parameter in @SuppressWarnings
@SuppressWarnings has the reverse job of the warnings described above. It tells the compiler to turn off warning messages that would otherwise be generated when a class or method is compiled. It is applied to a class or method in the same way as the other annotations. Unlike @Override and @Deprecated, however, @SuppressWarnings takes a parameter, and that parameter is what makes it specific.
The source's example passes the string "deprecation", written as @SuppressWarnings("deprecation"). This tells the compiler to stop reporting deprecation warnings for the annotated class or method. Because the string names one category, a programmer who uses this annotation is choosing exactly which kind of warning to silence. Other warnings in the same code are still reported, which is what makes suppression targeted rather than blanket.
Comparing @Deprecated and @SuppressWarnings
The two annotations sit on opposite sides of the same warning system. One is written by the author who wants the compiler to report uses of an item. The other is written by a programmer who wants a particular category of report silenced for a class or method.
| Annotation | Who writes it | Effect on the compiler | Takes a parameter? |
|---|---|---|---|
| @Deprecated | Code author marking an element as obsolete | Generates warnings whenever the item is used | No |
| @SuppressWarnings | Programmer compiling a class or method | Turns off the named category of warnings | Yes, the category name |
Purpose of @Deprecated compared with @SuppressWarnings
Mistakes Beginners Make with Annotations
Common mistake Expecting an annotation to change how the method runs
Why it failsAn annotation has no direct effect on the program it annotates. Its value comes from what the compiler checks against it.
Do this insteadAsk what the compiler will verify or report, not what the running code will compute differently.
Common mistake Assuming @Override makes a method override a superclass method
What it looks likeWriting @Override on a method whose name is spelled with different capitalization from the superclass method
Why it fails@Override states an intention and asks the compiler to verify it. It does not create the match.
Do this insteadMake the signature match the superclass method, and use @Override so that any mismatch is reported as an error.
Common mistake Using @SuppressWarnings with no parameter and treating it as a blanket switch
Why it failsThe annotation takes a parameter that names the category of warnings. The parameter is what makes suppression targeted.
Do this insteadName the specific category, such as "deprecation", so other warnings are still reported.
Common mistake Thinking @Deprecated stops the item from working
Why it failsA deprecated item remains part of the language so that old code keeps working. The annotation signals obsolescence through warnings.
Do this insteadTreat deprecation as a warning to plan a replacement, not as a removal.
Trace an Override Check
A superclass Shape declares a method draw with no parameters. A subclass Circle writes @Override followed by a method named Draw with no parameters. Trace what the compiler does, and say whether the declaration is accepted or reported as an error. Then explain what would change if the @Override annotation were removed.
Hints
- Start from the annotated subclass method and ask whether a matching superclass method exists.
- Compare the names character by character, paying attention to capitalization.
- Without the annotation, is there any claim for the compiler to verify?
Summary of Annotations and Checks
- 1A Java annotation has no direct effect on the program it annotates; its value comes from what a compiler can check against it.
- 2@Override states that a method replaces a superclass method with the same signature, and the compiler reports an error when no such method exists.
- 3@Deprecated marks a class, method, or variable as obsolete but still usable, so the compiler can warn when it is used.
- 4@SuppressWarnings takes a parameter naming the category of warnings to turn off, making suppression targeted rather than blanket.
At a glance
- A Java annotation has no direct effect on the program it annotates; its value comes from what a compiler can check against it.
- @Override is a claim that the compiler verifies, and it reports an error when no superclass method with the same signature exists.
- @Deprecated marks an item as obsolete but still usable, so the compiler can warn on each use.
- @SuppressWarnings takes a parameter naming the warning category to silence, which keeps suppression targeted.