Vasavi College of Engineering (Autonomous) · CSE · B.E. III Sem · R-24
Every real Java program
lives inside folders.
Until today every file you wrote sat loose in one src folder, and Eclipse quietly warned you about “the default package” every single time. Today that warning finally gets answered. You will also discover that an interface — the thing Class 11 told you can hold only empty method promises — has been allowed to carry real, working code since Java 8.
THE OFFICIAL SYLLABUS SENTENCE THIS HOUR FINISHES
“Classes and Interfaces: Singleton class, Abstract class, Nested class, Interface, Package.”
How a real Java project is laid out on disk
Open any professional Java project and the very first thing you notice is not the code — it is the folders. Nothing is loose. Every class sits inside a named box, and the box name is written at the top of the file. This hour teaches that layout, and finishes the syllabus sentence Class 15 started.
BY THE END OF THIS HOUR YOU CAN
- Create a package in Eclipse and by hand on the command line, and show where its folders sit on the hard disk.
- Import a class from another package three different ways, and say which one an examiner prefers.
- Debug the single most common package error — the file whose
packageline and folder do not match. - Explain why Java 8 let interfaces carry
defaultandstaticmethod bodies, and how the diamond clash is resolved.
THE ROAD THROUGH THIS CLASS
default methods — the Java 8 change that let an interface carry a working body, and the diamond clash it created
static methods in an interface — helpers that belong to the contract itself
Library interface with three methods, implemented by VasaviLibrary
PYQ P2·Q16b · 4M
mkdir, javac -d . and a fully-qualified java command
import — single class, wildcard, fully-qualified name, and the one package you never import
package line says one thing, the folder says another
CLASS 16 OF 60 · 13 PARTS (12 CORE-TAUGHT + 1 SELF-STUDY) · 10 PROGRAMS YOU TYPE YOURSELF · 1 PYQ · 2 ACTIVITIES WITH LOCKED SOLUTION SHEETS · FEEDS LAB 3
Before anything new — the exact sentence Class 11 left you with
Read this table as a checklist. Every row is something you were already taught. If a row feels unfamiliar, that is tonight's revision, because Parts 3, 4 and 5 all stand on it.
| YOU LEARNED IN | THE IDEA | THE SYNTAX | WHY TODAY NEEDS IT |
|---|---|---|---|
| Class 11 | An interface is a contract — a list of method names a class promises to provide | interface Payable | Everything in Parts 3–6 is an addition to this one idea. |
| Class 11 | implements signs the contract; the class must then supply every method | class Professor implements Payable | Part 3 asks what happens when you add a method to a contract people already signed. |
| Class 11 | A class may implement many interfaces (Java's answer to multiple inheritance) | implements A, B | This is exactly what makes the diamond clash in Part 3 possible. |
| Class 9 | static means “belongs to the class, not to an object” | ClassName.method() | Part 4 puts static inside an interface for the first time. |
| Class 15 | Runtime polymorphism through an abstract parent type | Reservation r = new ReserveBus(); | Interfaces do the same thing with the interface as the reference type. |
default methods only make sense once you have felt the problem they solve. That problem is Part 3, and it is the first thing we build.
ONE HONEST WORD ABOUT TODAY'S TWO TOPICS
Interface and Package sit next to each other in the syllabus sentence, but they answer two completely different questions. An interface answers “what must this class be able to do?” A package answers “where does this class live, and what is its full name?” One is about behaviour, the other about address.
They are taught in the same hour for a practical reason, not a theoretical one: Lab 3 needs both. In that lab you will write an attendance calculator in one package and a driver in another, and the driver has to import the calculator by its full address. Miss either half today and that lab turns into guesswork. Learn both today and the lab is thirty minutes of typing you already understand.
The day an interface was allowed to do something
We are going to build a perfectly good interface, watch the college ask for one small extra feature, and watch that one request break every class that had already signed the contract. Then one keyword — default — makes the breakage disappear. That keyword is the whole of Part 3.
Step 1 · The problem — adding one method to a contract everybody already signed
Here is the situation, in college terms. The campus has an entry-pass system. Every kind of pass — student pass, staff pass — must be able to tell the security guard whose pass it is. So we write an interface with exactly one promise in it, and two classes sign that contract.
Before the code, hold this picture: an interface is a list of promises. implements is a signature at the bottom of that list. Once a class has signed, Java checks — at compile time, every single time you build — that the class really did provide every promise on the list.
Now ask yourself the awkward question: what happens if, six months later, someone adds a new promise to the list? Every class that signed the old list is suddenly missing a method it never agreed to. Does it still compile? Hold that thought for two screens.
WHERE THIS FILE LIVES · ECLIPSE, EXACTLY AS ON THE LAB MACHINES
PACKAGE EXPLORER
HOW TO GET HERE · File › New › Java Project, name it JavaClass16, un-tick Create module-info.java, click Finish. Then right-click src › New › Class, name it CampusPassDemo, tick public static void main(String[] args), Finish. Leave the package box empty for now — from Part 8 onwards we stop doing that forever.
interface CampusPass{ String getHolderName();}class StudentPass implements CampusPass{ public String getHolderName() { return "Diya Sharma (1602-24-733-045)"; }}class StaffPass implements CampusPass{ public String getHolderName() { return "Prof. Ramesh Kumar (CSE)"; }}THE INTERFACE YOU ALREADY KNOW — FOUR LINES
Lines 1–4 are the whole contract: one method name, one semicolon. Then two classes keep it, each returning a different holder name.
Nothing new yet. This is Version 1, and it works perfectly — which is exactly why the next few pages will try to change it and see what breaks.
Piece 2 of 2 · main(). Ten lines, and the interesting part is the type on the left of each =.
public class CampusPassDemo{ public static void main(String[] args) { CampusPass p1 = new StudentPass(); CampusPass p2 = new StaffPass(); System.out.println(p1.getHolderName()); System.out.println(p2.getHolderName()); }}public on line 8 and line 16? Every method declared in an interface is automatically public, whether you write the word or not. So when a class implements it, the method must also be public — an override may never narrow access. Drop the word and you get “cannot reduce the visibility of the inherited method”. This is the single most common interface typo in the lab.
CampusPass and not StudentPass? Same reason as Class 15's Reservation r1. The security-gate code should not care which kind of pass arrived; it only cares that the object can answer getHolderName(). Typing the variable by the interface is how you say that in Java.
Step 2 · The college asks for one more feature — and 2 classes stop compiling
Six months later the security office says: “every pass should also be able to print itself at the gate kiosk.” Reasonable. So you add one line to the interface — a second promise, exactly the way Class 11 taught you.
StudentPass or StaffPass at all. And yet…NOW SCALE THAT UP AND FEEL THE REAL PAIN
Two classes is a two-minute fix. But this is precisely what happened to Oracle in 2014. They wanted to add forEach() to the List interface — an interface implemented by millions of classes in code written by other people all over the world. Adding one abstract method would have broken every one of those programs on the day they upgraded Java.
They could not add the method. They also could not leave List frozen forever. Java 8 solved it by inventing a third kind of interface method: one that arrives with a body already attached, so existing classes inherit a working version and nothing breaks. That is the default method.
Step 3 · The keyword: default
Seven cards, in order — the same shape this course uses for every new term. Plain words, a picture from real life, the syntax, the smallest example, what happens inside, the output, then one more example to lock it in.
In the simplest possible words: a default method is a method inside an interface that comes with a ready-made body. Classes that implement the interface get it free — they do not have to write it. If a class wants different behaviour, it may override it, exactly like any inherited method.
So an interface now has two kinds of entries: promises (no body, the class must supply one) and gifts (a body already provided, the class may keep it or replace it).
The hostel admission form. When you joined the hostel you signed a rule sheet. Two years later the warden adds a new rule: “lights out at 11 pm.”
Now the warden has two ways to add it. Way one: declare the rule blank — “every student must state their own lights-out time” — which means calling all 400 students back to fill in a new box. Nobody's old form is valid until they do. That is adding an abstract method. Way two: print the rule with the answer already filled in — “lights out at 11 pm unless you have applied for an exception”. Every old form stays valid instantly, and the handful of students in the night-shift internship apply for their exception. That is a default method: the rule arrives complete, and overriding it is the exception form.
One extra word, and — unlike an abstract method — a real brace pair:
Notice the contrast with Class 15's abstract method, which must end in a semicolon and must not have braces. Here it is the exact opposite: default requires a body. Write default void printPass(); with a semicolon and the compiler says “This method requires a body instead of a semicolon”.
Also note where the word does not go: never on the class's own version. The implementing class writes a plain public void printPass() when it overrides.
Six lines. One interface with a gift, one class that supplies nothing at all, and it still works:
Look at Empty. It has no body at all — not one line between its braces — and yet new Empty().hello() compiles and prints. Before Java 8 that was impossible: an empty class implementing an interface with any method in it was always a compile error.
When the compiler sees p1.printPass() it asks one question, in one fixed order:
(a) Does the object's own class define printPass()? If yes — run that, stop. (b) Does its superclass chain define it? If yes — run that, stop. (c) Does an interface it implements provide a default printPass()? If yes — run that.
The order matters and there is a name for it: the class always wins. A real class method beats an interface default, every time, even if the class inherited that method from a distant grandparent. An interface default is the last place Java looks — which is exactly what “default” means in ordinary English: the thing used when nothing better was supplied.
For the six-line example above, with a two-line main:
One line of output, produced by code that is not in the class that ran it. That is the whole novelty. Sit with it for a second: the body lives in Greeter, the object is an Empty, and the JVM found the body by walking up to the interface.
The point students miss: a default method may call an abstract method of its own interface. It does not need to know how that method works — only that whoever implements the interface will have supplied it.
Read line 7 carefully. getPercentage() calls getTotal(), which has no body anywhere in this interface. That is legal, because at runtime the call lands on the real object, and the real object must have getTotal() — the compiler enforced that when the class signed the contract. This is how the real Java library is built: a handful of promises, and a pile of gifts written on top of them.
Step 4 · Back to the broken program — one word repairs it
Same Eclipse project, a new class file so you keep the broken one for comparison. This version adds printPass() as a gift, and shows both halves of the story: StudentPass keeps the gift untouched, StaffPass overrides it because a staff pass shows lab access as well.
interface CampusPass{ String getHolderName(); // promise default void printPass() // gift { System.out.println("===== VCE CAMPUS PASS ====="); System.out.println("Holder : " + getHolderName()); }}class StudentPass implements CampusPass{ public String getHolderName() { return "Diya Sharma (1602-24-733-045)"; } // printPass() NOT written here — inherited from the interface} ONE NEW WORD · default ON LINE 5
Line 3 is the old kind of interface method: a name and a semicolon, a pure promise. Line 5 is the new kind — default, with a body. The interface is now giving a free gift, not just asking.
Look at line 18: StudentPass never writes printPass(), yet it will have one. That is the gift arriving.
Piece 2 of 3 · refusing the gift. A class is always allowed to write its own version instead.
class StaffPass implements CampusPass{ public String getHolderName() { return "Prof. Ramesh Kumar (CSE)"; } public void printPass() // override: the class wins { System.out.println("===== VCE STAFF PASS ====="); System.out.println("Holder : " + getHolderName()); System.out.println("Access : LABS + LIBRARY (24x7)"); }}THE RULE, IN FIVE WORDS: THE CLASS ALWAYS WINS
Line 28 writes printPass() inside StaffPass. Now there are two versions available — the interface's default and this one.
Java never hesitates: the class's own method wins. The default is only used when the class stayed silent, as StudentPass did.
Piece 3 of 3 · one call, two different outputs. Ten lines that prove both halves at once.
public class DefaultPassDemo{ public static void main(String[] args) { CampusPass p1 = new StudentPass(); CampusPass p2 = new StaffPass(); p1.printPass(); p2.printPass(); }}StudentPass — the class that never wrote printPass() at all — compiled without one error.getHolderName() with no object in front of it. That is the card-7 pattern: the interface's own body calling its own promise. When p1.printPass() runs, that call lands on the StudentPass object and returns Diya's name. Same body, different answer per object.
printPass() in an abstract class? A very fair question, and it has a hard answer: StudentPass might already extend something else. Java allows only one extends. An interface can be added to a class that already has a parent, which is exactly why Oracle needed the interface route in 2014.
Step 5 · The price of the gift — the diamond clash
Class 11 told you Java refuses multiple inheritance of classes, and gave you the reason: if two parents supply the same method, the child has no way to choose. Interfaces were safe from that problem because their methods had no bodies — there was nothing to choose between.
Default methods put the bodies back. So the old problem returns, in a new place. Java 8 had to answer it, and the answer is short and exact.
THE CLASH · ONE CLASS, TWO INTERFACES, ONE METHOD NAME
JAVA NEVER PICKS FOR YOU · IT STOPS THE BUILD AND MAKES YOU PICK
interface Wifi{ default void connect() { System.out.println("Connected to VCE-WIFI"); }}interface Lan{ default void connect() { System.out.println("Connected through LAN cable"); }}TWO GIFTS · IDENTICAL NAME
Wifi gives a free connect(). Lan also gives a free connect(). Each on its own is fine.
Now imagine one class taking both gifts. Which connect() does it get? Neither is more correct than the other, so Java refuses to guess — and that refusal is what the next piece resolves.
Piece 2 of 2 · the clash, and the only legal fix. Seventeen lines, and two of them use syntax that exists for exactly this situation.
class LabComputer implements Wifi, Lan{ public void connect() // MANDATORY — without this, no compile { Wifi.super.connect(); Lan.super.connect(); System.out.println("Lab computer online on both links."); }}public class DiamondDemo{ public static void main(String[] args) { new LabComputer().connect(); }}class LabComputer in red: “Duplicate default methods named connect with the parameters () and () are inherited from the types Lan and Wifi”. Try it — seeing that message once is worth more than reading about it three times.
Wifi.super.connect() as one phrase. Plain super from Class 10 meant “my parent class”. There is no parent class here, and two candidate interfaces, so Java extended the syntax: put the interface name in front. Wifi.super means “the Wifi version, specifically”. It is only legal inside a class that directly implements Wifi.
THE THREE RESOLUTION RULES, IN THE ORDER JAVA APPLIES THEM
1 · The class wins. If the class (or any class it extends) has a real method with that signature, it is used and the interface default is ignored entirely. No error, no ambiguity.
2 · The more specific interface wins. If interface B extends A and both define the same default, a class implementing both gets B's version — B is nearer, and it clearly meant to replace A's.
3 · Otherwise the compiler stops and you choose. Two unrelated interfaces, same default — exactly our Wifi/Lan case. Java refuses to guess. You override and write InterfaceName.super.method() for whichever one you want, or write completely new behaviour, or call both.
| WHAT AN INTERFACE MAY HOLD | BEFORE JAVA 8 | JAVA 8 AND LATER | NEEDS A BODY? |
|---|---|---|---|
| Abstract method | yes | yes | No — ends in ; |
public static final constant | yes | yes | Must be given a value |
default method | no | yes | Yes — a real brace pair |
static method | no | yes (Part 4) | Yes |
| Constructor | no | no | — an interface is never instantiated |
| Instance field (ordinary variable) | no | no | — there is no object to hold it |
THE EXAM SENTENCE FOR THIS PART
“A default method is an interface method declared with the default keyword and a body. It was introduced in Java 8 so that new methods could be added to existing interfaces without breaking the classes that already implement them. Implementing classes inherit it and may override it. If two unrelated interfaces supply the same default method, the implementing class must override it and may select one using InterfaceName.super.methodName().”
Three sentences: what, why, the conflict rule. Write all three and there is nothing left to award marks for.
A helper that belongs to the contract, not to any object
Java 8 made a second change on the same day. Alongside default methods it allowed static methods inside an interface. This one is smaller, easier, and solves a tidiness problem you have already met without noticing.
Step 1 · The problem — where does a helper function go?
Stay with the campus-pass system. Every pass has a validity date, and lots of places in the program need to check “is this date string in the correct DD-MM-YYYY shape?”. That check does not belong to a particular pass — it is a rule about the pass format itself. So where do you put the method?
Collection + Collections, Path + Paths. A helper class whose only job was to sit next to an interface, with an s stuck on the end of its name.CampusPass.isValidDate("01-07-2026") — on the interface itself, with no object anywhere in sight.Step 2 · The three things that make it different from a default method
Students confuse these two constantly, because they arrived together and both have bodies. Three differences, and they are absolute.
It is not inherited. A default method becomes part of every implementing class. A static interface method does not. StudentPass.isValidDate(...) is a compile error — the class never receives it.
You must call it on the interface by name: CampusPass.isValidDate(...). That is not a restriction to work around; it is the point. The method belongs to the contract, not to anyone who signed it.
It cannot be overridden. Since no class inherits it, no class can replace it. A default method is a suggestion; a static interface method is a fixed fact about the interface.
It cannot call the interface's abstract methods. Recall card 7 of Part 3: a default method may call getHolderName() because at runtime there is an object. A static method runs with no object at all — this does not exist — so calling getHolderName() inside it gives exactly the Class 9 error you already know: “Cannot make a static reference to the non-static method”.
Step 3 · The working program — and the two errors, proven
Same Eclipse project, new class. Lines 26–27 are commented out on purpose: uncomment either one and the program will not build. Keeping them visible as comments is how you remember the rule.
interface CampusPass{ String getHolderName(); static boolean isValidPassId(String id) { if (id == null) { return false; } return id.startsWith("VCE-") && id.length() == 10; }}class StudentPass implements CampusPass{ public String getHolderName() { return "Diya Sharma"; }} static ON LINE 5 — A DIFFERENT KIND OF GIFT
A default method belongs to the objects. A static interface method belongs to the interface itself — it is a tool kept next to the contract, for anyone who needs it.
isValidPassId checks an id's shape. It needs no object at all, so making it static is honest. Lines 15–21 are just an ordinary implementing class.
Piece 2 of 2 · how you call it — and two ways you cannot.
public class StaticInterfaceDemo{ public static void main(String[] args) { System.out.println(CampusPass.isValidPassId("VCE-733045")); System.out.println(CampusPass.isValidPassId("733045")); System.out.println(CampusPass.isValidPassId(null)); // StudentPass.isValidPassId("VCE-733045"); // ERROR: not inherited // new StudentPass().isValidPassId("VCE-7"); // ERROR: not an instance method CampusPass p = new StudentPass(); System.out.println(p.getHolderName()); }}"VCE-733045" starts with VCE- and is exactly 10 characters. Line 28 → false: right length? no — and it fails the prefix test first. Line 29 → false, and crucially not a crash — the null guard on lines 7–10 catches it before startsWith is ever reached.null check earns its four lines. Delete lines 7–10 and line 29 throws NullPointerException — calling a method on nothing, the Class 8 error. A validation helper that crashes on bad input is not a validation helper. This is the habit Part H (Classes 17–20) will formalise.
default METHOD | static METHOD IN AN INTERFACE | |
|---|---|---|
| Has a body | yes | yes |
| Inherited by implementing classes | yes | no |
| Can be overridden | yes | no |
| Called as | obj.method() | Interface.method() |
Can use this | yes | no |
| Can call the interface's abstract methods | yes | no |
| Typical use | Add behaviour to an existing contract without breaking implementers | Keep a helper or factory next to the contract it belongs to |
List.of("a", "b", "c") — the modern way to make a small list — is a static method on the List interface. Before Java 9 you had to write Arrays.asList(...), borrowing a helper class from a different package. You will meet List properly in Unit 4; note now that the feature you learned in this hour is the one that made that shorter syntax possible.
An interface with nothing inside it
You are about to see a real interface from the Java library whose entire body is empty. No methods, no constants, nothing between the braces. It sounds like a mistake or a joke. It is neither — and by the end of this part you will see why it is the cleverest small idea in the language.
Step 1 · The problem — how does code ask “is this thing allowed?”
Here is a real requirement. The college app stores objects to a file so they survive a restart — your saved attendance, your timetable. But some objects must never be written to disk: a live password object, an open network connection.
So the saving routine needs to ask each object one question before it writes it: “are you the kind of thing that is permitted to be saved?” Notice what that question is not. It is not asking the object to do anything. There is no behaviour to demand, no method to call. It is asking about the object's category.
Every tool you have so far is a tool for demanding behaviour. An abstract class demands a method. An interface demands a method. But this requirement has no method in it at all.
So what would you do? Add a boolean canBeSaved() that every class returns true from? That is 400 identical methods and any class can lie. Keep a list of approved class names somewhere? That list will drift out of date the week after you write it. Hold the difficulty — the answer is a shape you have not seen yet.
Step 2 · The term: marker interface
Same seven-card ritual. This term is short but genuinely confusing the first time, so we go slowly and give it two examples rather than one.
In the simplest possible words: a marker interface is an interface with no methods and no constants at all. A class implements it not to gain behaviour, but purely to be labelled — so that other code can check the label and act differently.
It carries no instructions. It carries a fact: “this class is one of those.”
The green sticker on the lab machines. Walk into the CSE lab and some monitors have a small green sticker on the corner. The sticker does nothing. It has no text, no barcode, no instructions. It cannot make the machine faster.
But the lab attendant knows what it means: those machines have the exam software installed. On exam day the attendant walks the row, looks only for the sticker, and allocates only those machines. The sticker adds no ability — it adds membership of a group, and someone else's procedure treats members differently. That is exactly a marker interface. implements Serializable is the sticker; the JVM's saving routine is the attendant.
There is almost nothing to it, and that is the surprise:
Empty braces. The class that implements it has no obligations whatsoever — there is nothing to implement. And that empty interface is now a legal Java type, which is the part that does the real work.
The label is only useful if something checks it. The checking tool is the instanceof operator from Class 11 — it asks “is this object of that type?” and answers true or false:
Read that if aloud: “if this object carries the HostelResident label…”. No method was called on obj. Nothing was demanded of it. Its type alone answered the question.
When you write class Student implements HostelResident, the compiler records that fact inside Student.class — the compiled file lists every interface the class implements, even the empty ones. That list travels with the class for the whole life of the program.
At runtime instanceof simply reads that list. So the “sticker” is not a fiction — it is a real entry in a real compiled file, and checking it costs almost nothing.
The two library markers work exactly this way. java.io.Serializable is empty; the saving machinery checks for it and refuses (throws NotSerializableException) if the label is absent. java.lang.Cloneable is empty; Object.clone() checks for it and throws CloneNotSupportedException if it is missing. In both cases the interface is empty and the checking code lives elsewhere. That split is the whole design.
Full runnable program next screen; here is what it prints, so you know what you are aiming at:
Two objects of two classes that are otherwise identical in every way, treated differently by the same line of code — because one of them carries a label that has nothing inside it.
A marker also works as a compile-time guard, not just a runtime check. Write a method that accepts only labelled objects:
Now allotRoom(someDayScholar) will not compile at all. The mistake is caught while you type, not at 2 a.m. in production. Same empty interface, used as a parameter type instead of an instanceof test — and that is often the stronger way to use it.
Step 3 · The full program — a marker doing real work
Two student classes, identical except for one word on the class declaration line. One method decides their fate.
interface HostelResident{ // deliberately empty — this is a MARKER}class Learner{ String name; Learner(String studentName) { name = studentName; }}AN INTERFACE WITH NOTHING IN IT
Lines 1–4 declare HostelResident and then declare nothing at all. No methods, no constants. It looks pointless.
It is not. It is a label. A class that implements it is saying “I am one of these” — and in the third piece we ask Java that exact question.
Lines 6–14 are just an ordinary parent class holding a name.
Piece 2 of 3 · two children, and only one wears the label. Compare line 16 with line 24 — that difference is the whole experiment.
class BoarderStudent extends Learner implements HostelResident{ BoarderStudent(String studentName) { super(studentName); }}class DayScholar extends Learner{ DayScholar(String studentName) { super(studentName); }}SPOT THE DIFFERENCE · IT IS TWO WORDS
Line 16: extends Learner implements HostelResident.
Line 24: extends Learner — and nothing else.
Both bodies are otherwise identical: a constructor that hands the name up with super. Neither class gained a single method from the marker, because the marker has none to give.
So the two classes behave identically… until somebody asks about the label.
Piece 3 of 3 · asking the question. Here the empty interface finally does something — and it changes the output.
public class MarkerDemo{ static void checkAccommodation(Learner l) { if (l instanceof HostelResident) { System.out.println(l.name + " -> Allot a hostel room."); } else { System.out.println(l.name + " -> Day scholar, no room needed."); } } public static void main(String[] args) { checkAccommodation(new BoarderStudent("Aarav Reddy")); checkAccommodation(new DayScholar("Sneha Iyer")); }}implements HostelResident — pointing at an interface with nothing in it — changed the output.implements HostelResident to line 24 as well, save, run. Both lines now say “Allot a hostel room.” Remove it from line 16 instead and both become day scholars. Nothing else in the file changes. That is a label doing all the work.
l.name work on line 38? The parameter is typed Learner, and name is a Learner field, so both subclasses have it. Note we did not type the parameter as HostelResident — that would only accept boarders and there would be nothing to decide.
LEARN THIS SENTENCE · IT IS THE DEFINITION AN EXAMINER ACCEPTS
“A marker interface (or tagging interface) is an interface that declares no methods and no fields. A class implements it only to mark itself as belonging to a category, so that the JVM or other code can detect that category using instanceof and behave differently. Examples in the Java library are java.io.Serializable, java.lang.Cloneable and java.rmi.Remote.”
Add the mechanism in one more line: “the interface itself contains no code — the behaviour lives in the code that checks for the marker, e.g. object serialization throws NotSerializableException when the marker is absent.” Definition + two named examples + the mechanism = full marks.
THE MODERN FOOTNOTE — SAY THIS AND YOU SOUND LIKE YOU READ AHEAD
Since Java 5 there is a newer tool for labelling: annotations, the @ things you have seen on @Override. Much new code uses an annotation where old code used a marker interface. But markers are not obsolete, and for one solid reason: a marker interface is a type, so the compiler can enforce it in a parameter list (card 7 above). An annotation cannot do that — it is only visible to tools that go looking for it. Both are examinable; markers are what this syllabus asks for.
The library question, answered in full
One question from the interface topic has appeared in your question paper, and it is a write-a-program question worth four marks. Everything needed for it you already have — interface and implements from Class 11, sharpened by Parts 3, 4 and 5 today. We will not merely answer it. We will build it the way you should build it in the examination hall: read, decode, sketch, plan, type, run, and only then write the final sheet.
Step 1 · The question, and what is actually being marked
Library having the methods drawBook(), returnBook() and checkStatus(). Implement this interface in a class named VasaviLibrary and demonstrate the working of all three methods.interface Library, (2) exactly three method declarations inside it — drawBook(), returnBook(), checkStatus() — with no bodies, (3) a class VasaviLibrary that says implements Library, (4) a public body for all three methods in that class, (5) a main that creates the object and calls all three, so something is actually demonstrated.interface and implements (Class 11) · methods in an interface are implicitly public abstract (Class 11, re-checked in Part 3 today) · a field in an interface is implicitly public static final (Class 9 + Class 11) · interface-typed reference holding a subclass object (Class 11) · constructor and this (Class 7) · if/else (Class 5) · string concatenation in println (Class 4) · one public class per file (Class 3)main, ½ mark for writing the output. Write all five pieces even if rushed. A short, complete program beats a long, half-finished one every single time.THESE NAMES ARE FIXED BY THE QUESTION — DO NOT IMPROVE THEM
The paper printed six names, and you must reproduce them character for character: Library, drawBook(), returnBook(), checkStatus(), VasaviLibrary, and the keyword implements.
Every year somebody writes issueBook() instead of drawBook(), or LibraryImpl instead of VasaviLibrary, because it “sounds more professional”. It costs marks and gains nothing. In the exam hall, copying the question's own vocabulary is free marks — save your creativity for the message strings inside the methods, where nobody has told you what to write.
“Draw a book” is Indian library English for borrow / issue. It has nothing to do with drawing pictures. In our own Central Library at Vasavi the counter register literally has columns headed Books drawn and Books returned, so the question is using the exact word printed on the register. Read the three methods as borrow · give back · tell me where I stand, and the program writes itself.
Notice also what the question did not ask for: no file handling, no arrays of books, no user input. Three methods and a demonstration. Do not build more than was asked — extra unasked machinery is extra chances to make a compile error under time pressure.
Step 2 · The diagram to sketch before typing anything
Thirty seconds with a pen buys you a program that cannot be structurally wrong. This is the same UML sketch you drew for the abstract-class question in Class 15, with one changed convention: because Library is an interface and not an abstract class, the connector is a dashed line (UML calls that realization) instead of a solid one, and the box carries the stereotype «interface». Press the button under the diagram to build it one piece at a time.
ONE CONTRACT · ONE IMPLEMENTER · ONE INTERFACE-TYPED REFERENCE
PAPER 2 · Q16(b) · DASHED CONNECTOR = implements · SOLID CONNECTOR WOULD MEAN extends
Step 3 · The plan, in the order you should type it
Six steps. The ordering matters: writing VasaviLibrary before Library means Eclipse fills your editor with red squiggles for a method that does not exist yet, and under exam pressure red ink on the screen makes people delete correct code.
Write the contract first: interface Library, then the three declarations, each ending in a semicolon and nothing else. No public, no abstract, no braces. Those two keywords are added by the compiler for you (Class 11) — writing them is legal but wastes ink, and writing braces is a compile error.
Decide what checkStatus() will report, because that decision creates the only state the program needs. A status of what? Of how many books this member currently holds. So VasaviLibrary needs an int booksHeld field. This is the thinking step, and it is what separates a program that runs from a program that means something: drawBook() increases the count, returnBook() decreases it, checkStatus() reports it. The three methods are now genuinely related instead of being three unrelated printlns.
Write class VasaviLibrary implements Library. Add the two private fields and a constructor that takes the member's name. Private fields plus a constructor is encapsulation from Class 8 — you are not adding it to show off, you are adding it because booksHeld must never be changed from outside except through the three contract methods.
Supply all three bodies, each starting with the word public. This is the line beginners lose marks on, so here is the reason once more: an interface method is implicitly public, and Java forbids an override from being less visible than what it overrides. Omit public and the method becomes package-private, which is narrower, and the compiler stops you by name.
Add a little intelligence inside the bodies with if/else: refuse to draw a fourth book, refuse to return when nothing is held. Two if statements you have known since Class 5, and they turn the answer from a toy into something an examiner reads twice.
Write public class LibraryDemo with main. Create the object through an interface-typed reference — Library member = new VasaviLibrary("Diya Sharma"); — then call all three methods. Typing the reference as Library rather than VasaviLibrary is a deliberate choice and it is worth a sentence in your explanation, because it is the sentence that proves you understand interfaces rather than having merely used one.
WHY WE ARE ABOUT TO USE AN INTERFACE FIELD TOO
The rule “a member may hold at most three books” is a library rule, not a property of one member. It belongs to the contract, not to the implementer. And an interface is allowed to hold a field: recall from Class 11 that any field written inside an interface is automatically public static final — a shared, unchangeable constant.
So we write int MAX_BOOKS = 3; inside Library. Three words, no modifiers, and every class that implements Library can use MAX_BOOKS as if it owned it. Capital letters with underscores is the Java naming convention for constants — you saw it in Integer.MAX_VALUE. This is the small “beyond the expected answer” touch for this question: it costs one line and it demonstrates a second fact about interfaces.
Step 4 · Type it in Eclipse and run it
All three types — the interface, the implementing class and the demo class — go into one file, because only one of them is public and that one shares the file's name. This is the same one-file arrangement you have used since Class 15, and it is exactly what you write on paper in the exam.
WHERE THIS FILE LIVES · ECLIPSE, EXACTLY AS ON THE LAB MACHINES
PACKAGE EXPLORER
HOW TO GET HERE · Right-click src › New › Class. In the New Java Class window type LibraryDemo in the Name box, tick public static void main(String[] args), leave Package empty, click Finish. Eclipse opens the new tab; type the interface above the generated class. Run with the green ▶ arrow, or Ctrl + F11.
interface Library{ int MAX_BOOKS = 3; // implicitly public static final void drawBook(); void returnBook(); void checkStatus();}EIGHT LINES, AND THE EXAMINER IS ALREADY GIVING MARKS
Write this much and stop. An interface is three method names with semicolons plus, here, one constant. No bodies, no braces after the method names.
Line 3 is worth knowing: a field in an interface is automatically public static final. You never type those three words — but if asked, that is the answer.
drawBook and returnBook are the method names the question specifies, so they are kept exactly. checkStatus is the third one it asks you to add.
Piece 2 of 4 · the class starts keeping the contract. Fields, constructor, and the first of the three promised methods.
class VasaviLibrary implements Library{ private String memberName; private int booksHeld; VasaviLibrary(String member) { memberName = member; booksHeld = 0; } public void drawBook() { if (booksHeld < MAX_BOOKS) { booksHeld++; System.out.println(memberName + " drew a book. Books held: " + booksHeld); } else { System.out.println(memberName + " cannot draw. Limit of " + MAX_BOOKS + " reached."); } }THE ONE WORD THAT COSTS MARKS
Line 21 says public void drawBook(). That public is not optional. Interface methods are public, and an implementing class may never reduce visibility — drop the word and the compiler refuses the file.
Notice line 23 uses MAX_BOOKS with no prefix. The class implements Library, so it inherits the constant and can name it directly.
Piece 3 of 4 · the other two promised methods. Same shape as drawBook — read it quickly.
public void returnBook() { if (booksHeld > 0) { booksHeld--; System.out.println(memberName + " returned a book. Books held: " + booksHeld); } else { System.out.println(memberName + " has no book to return."); } } public void checkStatus() { System.out.println("STATUS -> " + memberName + " | held: " + booksHeld + " | can draw " + (MAX_BOOKS - booksHeld) + " more"); }}ALL THREE PROMISES NOW KEPT
drawBook, returnBook, checkStatus — the class is complete, so new VasaviLibrary(...) becomes legal. Implement only two of the three and the compiler names the missing one at you.
Both methods guard before acting: you cannot return a book you do not hold, and you cannot exceed the limit. That is the Class-14 habit, still paying off.
Piece 4 of 4 · main(), driving it to the limit. Sixteen lines that deliberately try to draw a fourth book.
public class LibraryDemo{ public static void main(String[] args) { Library member = new VasaviLibrary("Diya Sharma"); member.drawBook(); member.drawBook(); member.checkStatus(); member.returnBook(); member.checkStatus(); member.drawBook(); member.drawBook(); member.drawBook(); // the fourth book — refused }}Library itself — it has no code at all.= is Library, an interface, and you cannot write new Library() anywhere in Java. Yet Library member = ... is perfectly legal, because the interface is being used only as a label on the reference, never to build the object. The object on the heap is a complete VasaviLibrary.
booksHeld had simply gone to 4 with no check, that would be the bug — and it would be a silent one.
package com.vce.library; and live in the folder com\vce\library\. Hold that thought for eleven minutes.
Step 5 · Line by line — every decision, explained
THE CONTRACT · LINES 1 TO 8
Line 1 — interface Library The keyword is interface, not class. Nothing else on the line, and the name is capital-L Library exactly as printed in the question. This one line is the first thing an examiner's eye lands on.
Line 3 — int MAX_BOOKS = 3; A field in an interface. Written with no modifiers, but the compiler treats it as public static final int MAX_BOOKS = 3; — shared by every implementer, readable from anywhere, and permanently 3. Try MAX_BOOKS = 5; anywhere in the program and you get The final field Library.MAX_BOOKS cannot be assigned. That is not a limitation, it is the point: a library rule should not be editable by a member.
Lines 5, 6, 7 — the three promises. Each one is a return type, a name, an empty parameter list, and a semicolon. There are no braces, no public, no abstract. The compiler silently adds public abstract to each. Count them out loud when you write them — draw, return, check — because the whole question hinges on there being three.
Line 8 — the closing brace. The interface is finished, and it contains not one executable statement. Eight lines that do nothing and decide everything.
THE IMPLEMENTER · LINES 10 TO 52
Line 10 — class VasaviLibrary implements Library The keyword is implements, not extends. From this moment the class has a debt: three method bodies. Until all three exist, the file will not compile, and Eclipse will show a red marker on line 10 itself — not on the missing method, because the missing method is not there to mark.
Lines 12–13 — the state. private so that no outside code can set booksHeld to 99 and bypass the limit. This is encapsulation from Class 8 doing real work rather than being demonstrated for its own sake.
Lines 15–19 — the constructor. Same name as the class, no return type. The parameter is deliberately called memberName, identical to the field, which is exactly why line 17 needs this.memberName = memberName; — this. means “the field of the object I am building”, the bare name means “the parameter”. Line 18 sets the count to zero; a brand-new member holds nothing.
Line 21 — public void drawBook() The word public is compulsory, and this is the single highest-frequency mistake in this question. The interface promised a public method; an implementer may not deliver something narrower. Drop the word and Eclipse says Cannot reduce the visibility of the inherited method from Library.
Line 23 — if (booksHeld < MAX_BOOKS) Notice what is not written: Library.MAX_BOOKS. Because VasaviLibrary implements Library, the constant is inherited into the class's own namespace and the short name works. Writing the long form is also correct, just longer.
Lines 25–26 — the order matters. Increment first, then print. Print first and the message would say “Books held: 0” after successfully drawing a book, which is a bug that produces perfectly formatted nonsense — the worst kind.
Lines 28–31 — the else. The fourth request is not an error and not a crash; it is a refusal, printed politely, with the limit named so the member knows why. Note MAX_BOOKS being concatenated straight into the string on line 30: an int next to a String with + is automatically converted to text (Class 4).
Line 36 — if (booksHeld > 0) The mirror-image guard. Without it, returning a book you never took would drive booksHeld to −1, and checkStatus() would then cheerfully offer you four books. One if prevents an entire family of nonsense.
Lines 49–50 — one statement, two lines. Java does not care where you break a line; the statement ends at the semicolon on line 50. It is split purely so a human can read it. The bracket in (MAX_BOOKS - booksHeld) is essential: without it, + would treat both numbers as text and print "32" instead of 1. That is a genuinely famous beginner trap and it is why we wrote the brackets in.
THE DEMONSTRATION · LINES 54 TO 69
Line 54 — public class LibraryDemo The one public type in the file, so the file must be named LibraryDemo.java. Library and VasaviLibrary are deliberately left package-private; that is legal and normal for a single-file program.
Line 58 — the most examinable line in the answer. Library member = new VasaviLibrary("Diya Sharma"); — interface type on the left, concrete class on the right. The compiler checks every later call against Library; the JVM runs the bodies found in VasaviLibrary. If a second implementer were ever written, line 58 is the only line that would need to change. That sentence is worth writing in your answer.
Lines 60–67 — a story, not a list. Draw, draw, check, return, check, draw, draw, draw. The sequence is chosen so the console proves three things without a word of commentary: the counter goes up, it goes down, and the limit actually holds. Random calls would compile and run just as well but would demonstrate far less — and the question says “demonstrate”.
Step 6 · The output, and precisely why it comes out that way
Here is the console again on its own, the way you would copy it under an Output: heading on your answer sheet. Then three reasons, in order, for why it reads like this and could not read otherwise.
WHY THIS OUTPUT — THREE REASONS, IN ORDER
1. Why any output at all? Because main exists, creates a real object and calls the methods. This sounds too obvious to state, and yet a perfectly written Library plus VasaviLibrary with no main prints nothing and loses the demonstration mark. The question said “demonstrate”; demonstration means output.
2. Why do the numbers march 1, 2, then 1, then 2, 3? Because booksHeld lives inside the one object that member points at, and every call operates on that same object. It is not reset between calls, and there is no second copy. Each method reads and updates the same field — which is why the third line can honestly report “held: 2” after two draws. If you had written booksHeld as a local variable inside drawBook(), every line would say “Books held: 1” forever. State belongs to the object.
3. Why does the eighth call refuse instead of printing “Books held: 4”? Because at that moment booksHeld is 3, MAX_BOOKS is 3, and 3 < 3 is false. The if hands control to the else, which prints the refusal and — crucially — never touches booksHeld. The count stays at 3, so the rule was not merely reported, it was enforced.
And the order? Java runs statements top to bottom and println writes immediately, so the console order is simply lines 60 to 67 in sequence. Swap any two calls in main and the console swaps with them. There is no hidden cleverness anywhere in this program — which is exactly what you want in an exam answer you may have to defend aloud in the viva.
One more example — the reason this question uses an interface at all
A fair objection: “we could have written VasaviLibrary as an ordinary class with those three methods and got the same eight lines of output — so what did the interface buy us?”. That objection deserves a real answer, not a slogan, so here is a second complete program. Same Library contract, word for word. Two implementers now: the physical counter in our Central Library, and the DELNET e-book portal that the college subscribes to.
READ THIS BEFORE YOU TYPE — THIS FILE NEEDS A NEW ECLIPSE PROJECT
The file below declares interface Library again, and a class VasaviLibrary again. If you save it into the same src folder as LibraryDemo.java, Eclipse will paint both files red before you even press Run, with the message:
The type Library is already defined
And it is right to complain. Both files sit in the same place — the default package — and two different types cannot share one name in one place, exactly as two files cannot share one name in one Windows folder. So make a fresh project for this experiment: File › New › Java Project, name it JavaClass16b, un-tick Create module-info.java, Finish.
Hold on to this error. You have just met, by accident, the precise problem that Part 7 exists to solve. Making a whole new project every time two names collide is not a solution — real programs need two classes called Library to coexist peacefully in one program. The tool that allows it is called a package, and it is eleven minutes away.
interface Library{ void drawBook(); void returnBook(); void checkStatus();}class VasaviLibrary implements Library{ public void drawBook() { System.out.println("Counter : book stamped, due back in 14 days."); } public void returnBook() { System.out.println("Counter : book received at the desk, no fine."); } public void checkStatus() { System.out.println("Counter : 2 of 3 books on your card."); }}THE SAME SIX-LINE CONTRACT AS BEFORE
Lines 1–6 are the Library interface again. Lines 8–24 are the physical counter keeping it — three methods, each printing what a real counter clerk would say.
Nothing new so far. The point of this program arrives in the next piece.
Piece 2 of 3 · a second, totally different desk. Same three method names; completely different behaviour behind them.
class DigitalLibrary implements Library{ public void drawBook() { System.out.println("DELNET : e-book unlocked for 7 days."); } public void returnBook() { System.out.println("DELNET : licence released early, slot freed."); } public void checkStatus() { System.out.println("DELNET : 1 active licence, 4 slots free."); }}ONE CONTRACT, TWO HONEST ANSWERS
A physical book gets stamped for 14 days. An e-book gets unlocked for 7. Neither desk is wrong — they are different services that agreed to answer the same three questions.
That agreement is what an interface actually buys you, and the next piece cashes it in.
Piece 3 of 3 · the payoff. Thirteen lines. Watch how the loop never once mentions which desk it is talking to.
public class TwoDesksDemo{ public static void main(String[] args) { Library[] desks = { new VasaviLibrary(), new DigitalLibrary() }; for (Library desk : desks) { desk.drawBook(); desk.checkStatus(); } }}if asking which kind of desk this is, and the words VasaviLibrary and DigitalLibrary appear nowhere inside the loop. The loop only knows Library. Yet the console shows two completely different behaviours.{ ... } here is not a code block — it is an array initialiser, which is data. Allman applies to blocks: classes, methods, if, loops. It never applies to a list of values.
class MobileVanLibrary implements Library tomorrow, drop it into the array on line 48, and lines 50–54 keep working unchanged. That is what a contract is for, and it is the sentence to put at the end of your exam answer.
A PICTURE FOR THIS — THE THREE-PIN SOCKET
The wall socket in your lab has a fixed shape. It does not know or care what is being plugged into it — a table fan, a phone charger, a soldering iron. The socket publishes a shape; anything that matches the shape works; the socket's own wiring never changes when a new device is invented.
Library is that shape. drawBook(), returnBook(), checkStatus() are the three pins. VasaviLibrary and DigitalLibrary are two devices with matching plugs and wildly different insides. And main is the socket, which never had to be rewired.
Step 7 · The model answer, as it should look on your sheet
The 69-line version was for learning. In a four-mark answer with about ten minutes of writing time you write the short, complete version below — every marked deliverable present, nothing decorative. Both versions score full marks; only one of them you can finish in time.
Q16(b) Write a Java program to create an interface Library having the methods drawBook(), returnBook() and checkStatus(). Implement it in a class VasaviLibrary. [4M]
An interface in Java is a reference type that contains only method declarations and constants. Its methods are implicitly public abstract and its fields implicitly public static final. A class uses the keyword implements and must supply a public body for every declared method.
Program:
Output:
Book drawn. Books held: 1
Book drawn. Books held: 2
Books currently held: 2
Book returned. Books held: 1
Books currently held: 1
Explanation: Library only declares the three methods; it has no code. VasaviLibrary supplies all three bodies, each marked public, and keeps the count in a private field. The reference member is of the interface type while the object is a VasaviLibrary, so the calls are checked against the interface at compile time and the implementing class's bodies run at runtime.
IF THE QUESTION ARRIVES SLIGHTLY CHANGED — FOUR LIKELY VARIANTS
“…with a constant for the maximum number of books.” Add int MAX_BOOKS = 3; inside the interface and say the sentence: a field in an interface is implicitly public static final. That is the 69-line version you already typed.
“…implement it in two classes.” That is TwoDesksDemo. Write the second implementer and, if there is time, hold both in a Library[] array to show one loop driving both.
“…pass the book title to drawBook().” Change the declaration to void drawBook(String title); and change it in the implementer too. A mismatched parameter list is a new, unrelated method, and the compiler will then complain that drawBook() was never implemented — a confusing error with a simple cause.
“…also explain the difference between an abstract class and an interface.” That comparison table is Class 15, Part 7. One line is enough here: an abstract class can hold constructors and ordinary state and a class may extend only one; an interface holds a contract and a class may implement many.
Step 8 · What actually goes wrong in this answer
Every mistake below is one we have seen in real answer sheets or real lab machines, and each one is paired with the exact message Eclipse or javac produces. Learn the messages: in the lab exam, reading the error correctly is half the repair.
public on the implementing methods
The commonest mistake in the whole question. void drawBook() inside VasaviLibrary is package-private, which is narrower than the interface's implied public. Real message: Cannot reduce the visibility of the inherited method from Library. Fix: one word, three times.
extends Library
Muscle memory from the inheritance classes. A class extends a class and implements an interface. Real message: The type Library cannot be the superclass of VasaviLibrary; a superclass must be a class. Refreshingly clear, for once.
Usually checkStatus(), because it is last and least obvious. Real message: The type VasaviLibrary must implement the inherited abstract method Library.checkStatus(). This is why you count the methods out loud when drawing the diagram.
void drawBook() { } inside the interface. Before Java 8 that was flatly illegal; today the compiler asks you to commit: Abstract methods do not specify a body. If you genuinely want a body there you must write default (Part 3) — but this question wants three plain promises.
new Library() in main
Written out of habit, to “test the interface”. Real message: Cannot instantiate the type Library. There is nothing to test — an interface has no code. Only new VasaviLibrary() builds an object.
MAX_BOOKS = 5; to “raise the limit”. Real message: The final field Library.MAX_BOOKS cannot be assigned. Interface fields are final whether you typed the word or not. To change the rule you edit the interface, not the running program.
issueBook(), Book_Library, LibraryImpl, status(). All compile perfectly and all lose marks, because the examiner is matching your identifiers against the printed question. Copy the question's spelling exactly.
(MAX_BOOKS - booksHeld)
Write "can draw " + MAX_BOOKS - booksHeld and you get The operator - is undefined for the argument type(s) String, int, because + already turned everything into text. Brackets first, then concatenate.
public types in one file
Marking both Library and LibraryDemo as public in LibraryDemo.java. Real message: The public type Library must be defined in its own file. One public type per file, and its name must match the file name.
All three classes perfect, no Output: heading on the sheet. The question says “demonstrate”. Five lines of text you already know, and they are marked. Never leave them out.
KEY TAKEAWAY
Five pieces, always in this order: the interface with three semicolon-terminated declarations → a class saying implements → three public bodies → an interface-typed reference holding a new implementer → a main that calls all three and prints. Then the output block and one sentence of explanation. That is a full-mark answer, and it fits comfortably in ten minutes.
The idea underneath is worth far more than the four marks: an interface separates what a thing must be able to do from how any particular thing does it. This year the paper called it a library; another year it is a Shape with area(), a Payable with calculatePay(), a Drawable with draw(). Identical skeleton, different vocabulary. Recognise the shape and the question is already half written.
Package — giving your code an address
Four items down, one to go. Everything in Classes and Interfaces so far has been about the shape of your code — singleton, abstract, nested, interface. package is the odd one out, and students find it strange for exactly that reason: it is not a shape at all. It is an address. And unlike every other keyword you have met, it changes something outside your file: it changes the folders on your disk.
Step 1 · The problem — and you met it eleven minutes ago
In Part 6 you were warned not to save TwoDesksDemo.java beside LibraryDemo.java, because Eclipse would refuse with “The type Library is already defined”. We dodged it by making a whole second project. That dodge does not scale, and here is the situation where it collapses completely.
Picture the real software our college actually runs. It is one program, and different teams built different parts of it:
Library2 or AudioLibraryClass — a permanent ugliness caused purely by a filing problem.com.vce.library.Library and com.vce.media.Library — different, so the compiler is content. Nobody renamed anything.Before reading on, notice how large this problem really is. Your program does not only contain your classes. It also contains the thousands of classes that came with the JDK, and any library your project uses later.
Java's own library has a class called List, a class called Date, a class called Timer, a class called Element — and in several cases more than one of each. There is a java.util.List and a java.awt.List. There is a java.util.Date and a java.sql.Date. If names had to be unique across the whole of Java, the very common word “Date” would have been used up in 1996 by one team and forbidden to everybody else forever.
So the question is not “how do I organise my files neatly?”. The question is: how can two different people, who have never met, both write a class called Date, and have both classes work in the same running program? That is what package answers.
Step 2 · The new term: package
This is the last new keyword of Unit II, so we will do the full ritual on it — plain words, a picture, syntax, what happens inside, and then the rules.
A package is a named group of related classes and interfaces. Two things happen when you put a class in a package. First, the class gets a longer, globally unique name: the package name, a dot, then the class name. Second — and this is the part that surprises everyone — the class must physically live in a folder tree whose names match the package name exactly.
So a package is simultaneously a naming device and a filing device. One word, two effects, and beginners who learn only the first half spend a whole afternoon fighting an error they cannot read.
Your phone's contact list has three people called Ramesh. You did not solve that by renaming two of them. You solved it because each contact carries something extra that is unique — the phone number. “Ramesh” is the short name you actually use; the number is what the network needs.
A closer picture still, because it explains the folder half too. There is a Gandhi Nagar in Hyderabad and a Gandhi Nagar in Vijayawada. Nobody renamed either colony. A letter still arrives, because the envelope carries the whole address, outermost part first — state, then city, then colony, then house. And crucially, the postman walks the address: he goes to that city, then that colony, then that house. The address is not a label stuck on the house, it is a route to it.
A Java package name is that envelope, and the JVM is that postman. com.vce.library.Library reads outermost-first exactly like an address — and to find the class, Java walks com, then vce, then library, as real folders. That is why the folders must exist and must be spelled correctly.
One line, and it must be the very first statement in the file — before any import, before any class. Only comments and blank lines may sit above it.
package com.college.attendance;
Lower case throughout, dots between the parts, semicolon at the end. There is exactly one such line per file — a file cannot be in two packages, just as a house cannot be at two addresses.
The dots are not decoration and they are not the “dot operator” you use for obj.method(). In a package name each dot means “go one folder deeper”.
com.college.attendance means three nested folders: a folder com, containing a folder college, containing a folder attendance, and the .java file sits inside that innermost one. Not one folder called com.college.attendance — three folders. Creating a single folder with dots in its name is the single most common package mistake on a lab machine, and we will look straight at it in Part 12.
What does the compiler actually do with that line? Three things, and they are all mechanical:
(a) It records the package inside the compiled .class file, so the class's real, permanent name becomes com.college.attendance.AttendanceCalculator. That long form is called the fully qualified name. The short name AttendanceCalculator is only a convenience for code that is nearby or that has imported it.
(b) It expects to find, and will produce, a matching folder tree. Compile with javac -d . and the compiler creates com\college\attendance\ for you and drops the .class file in. Part 9 does this live in a real terminal.
(c) At run time the JVM reverses the process: given com.college.attendance.AttendanceCalculator, it turns the dots back into folder separators and looks for com/college/attendance/AttendanceCalculator.class, starting from each location on the classpath. The name is the search path. That single sentence explains almost every package error message you will ever see.
Then your class goes into the default package — the unnamed package. That is where every single class you have written since Class 3 has lived, which is why none of this has bitten you yet.
The default package is fine for learning and useless for real work: it has no name, so its classes cannot be imported by any packaged class, cannot be given a unique identity, and collide with each other on sight — which is precisely the wall you hit in Part 6. Professional Java code is never in the default package. From this hour onwards, neither is ours.
The convention is to start the package name with an internet domain the organisation owns, written backwards. Vasavi College's domain is vce.ac.in, so college code would begin in.ac.vce..., and in practice teams shorten it to com.vce... or use a department word. Ours in this course are com.vce.library, com.college.attendance, com.college.app, com.college.util.
Why backwards? Because domains are already unique in the world — only one organisation owns vce.ac.in — so a name built from one is guaranteed not to clash with a stranger's code. And reversing it puts the widest part first, exactly like a postal address, so related packages sort together in a folder tree. This is also why real apps on your phone are named the way they are, which is Part 13's activity.
Naming rules to obey: all lower case (upper case is legal but marks you out as a beginner) · no Java keywords as a part, so no package called com.new.thing · no digit at the start of a part · no hyphens, since a hyphen is illegal in a Java identifier and therefore in a folder name here.
Step 3 · The one diagram that makes packages click
Everything above reduces to a single picture: the package name and the folder path are the same information written two different ways. Press the button under the figure to build it up, piece by piece.
ONE NAME · THREE FOLDERS · ONE FULLY QUALIFIED NAME
THE PACKAGE NAME IS THE FOLDER PATH · DOTS OUTSIDE, BACKSLASHES INSIDE · SAME INFORMATION
THE SENTENCE TO MEMORISE FOR THE EXAM — AND FOR THE LAB
“The package name must mirror the directory structure.” Every package error you will ever get comes from breaking that sentence in one of exactly three ways: the folders do not exist, the folders are spelled differently from the package line, or you are standing in the wrong folder when you run java. Learn to check those three things in that order and packages stop being mysterious.
Step 4 · Four things a package gives you
The examiner's favourite short question on this topic is “state the advantages of packages”. Here they are, each with the reason attached, because a list without reasons is forgotten by Tuesday.
The headline benefit and the one you just felt. com.vce.library.Library and com.vce.media.Library coexist happily. Java's own library depends on this: java.util.Date and java.sql.Date are two different classes with the same short name, both usable in one program.
You learned public, private and protected in Class 8. There is a fourth, and it is the one you get by writing no modifier at all: package-private. Such a member is visible to every class in the same package and invisible outside it. Without packages that level is meaningless — which is why it barely came up until today.
A 300-file program in one folder is unnavigable. Grouped as com.college.attendance, com.college.app, com.college.util, a stranger can find the attendance logic in four seconds. Your Lab 3 app is built exactly this way — deliberately, so that you feel the difference at a size where you can still see the whole thing.
A .jar file is essentially a zip of a package folder tree. Because the tree is predictable, any project can drop the jar onto its classpath and immediately use com.something.Thing. Every Java library you will ever add to a project arrives this way.
ACCESS MODIFIERS, NOW THAT PACKAGES EXIST — THE COMPLETE PICTURE
| Modifier you write | Same class | Same package | Subclass, other package | Anywhere |
|---|---|---|---|---|
private | ✓ | ✗ | ✗ | ✗ |
| nothing — package-private | ✓ | ✓ | ✗ | ✗ |
protected | ✓ | ✓ | ✓ | ✗ |
public | ✓ | ✓ | ✓ | ✓ |
Row 2 is the row that only starts to mean something today — and it is the row that bites in Lab 3.
THE TRAP THIS TABLE SETS FOR YOU IN LAB 3 — READ IT NOW, SAVE AN HOUR LATER
In Lab 3 you will put AttendanceCalculator in com.college.attendance and Main in com.college.app. Two packages. Now look at row 2 again: a class or method with no modifier is invisible from another package — and com.college.app is another package.
So class AttendanceCalculator must become public class AttendanceCalculator, its constructor must be public, and every method Main calls must be public. Miss any one of them and you get The type AttendanceCalculator is not visible or The method computePercentage(int, int) from the type AttendanceCalculator is not visible — errors that look like a broken import and are actually a missing keyword.
Rule of thumb from today onwards: if something is meant to be used from another package, mark it public. If it is a helper that nobody outside should touch, leave it with no modifier — and now that is a deliberate design decision rather than a blank space.
Creating a package, click by click
From this point on, every project in this course — including Lab 3, which is your next session — uses packages. So we are going to be pedantic: every window named, every field filled, every tick box accounted for. Follow along on your own machine. If Eclipse is not open, open it now and choose your eclipse-workspace folder.
Why the IDE for this part. Creating a package is exactly the kind of chore an IDE should do for you: one dialog, and Eclipse makes the folders, writes the package line into every new class, and keeps the two in agreement forever. That is the workflow you will use in the lab exam and in every project after this course.
And why we will not stop here. Eclipse hides the folders behind a tidy row of text in the Package Explorer, which is comfortable and slightly dishonest — it lets you use packages for two years without ever seeing what one is. So Part 8 does it the professional way in Eclipse, and then Part 9 does the same job by hand in Notepad++ and a terminal, where nothing is hidden and every folder is one you typed yourself. Learn it in both, and no package error will ever be able to confuse you.
Step 1 · A fresh project to work in
Keep today's package work separate from the five default-package files you already made. Same wizard as Lab 2, so this is a recap in three lines.
Create a Java Project
Create a Java project in the workspace or in an external location.
MENU PATH · File › New › Java Project · IF ECLIPSE ASKS “CREATE MODULE-INFO.JAVA?” IN A SEPARATE POP-UP, CLICK Don't Create · MODULES ARE A JAVA 9 FEATURE THIS COURSE DOES NOT USE, AND THE FILE ONLY CAUSES CONFUSING ERRORS AT THIS STAGE
Step 2 · Right-click src › New › Package
In the Package Explorer on the left, find your new project and click the small arrow to expand it. You will see two children: src (where your code goes) and JRE System Library [JavaSE-21] (Java's own classes, read-only). Right-click on src — not on the project name — then choose New › Package.
Java Package
Create a new package. The package will be created as a folder inside the source folder.
TYPE THE DOTS YOURSELF · com.college.attendance — ONE TEXT BOX, THREE FOLDERS · DO NOT RUN THE WIZARD THREE TIMES FOR com, THEN college, THEN attendance
The Name box takes the whole dotted name at once. Type com.college.attendance and press Finish. Eclipse silently creates three nested folders. Students who create a package called com, then another called college, then another called attendance end up with three separate top-level packages that are not nested at all, and nothing works.
If the Finish button is greyed out, read the message strip at the top of the dialog. Two causes cover almost every case: you typed a capital letter (Eclipse warns but allows it), or you used a Java keyword as one of the parts — com.new.attendance is rejected outright, because new can never be a folder name in a package.
Step 3 · What appeared — and the display setting nobody tells you about
Your Package Explorer now shows a single new row reading com.college.attendance. Notice the icon: it is a package icon, not a folder icon, and the whole dotted name sits on one line.
PACKAGE EXPLORER · FLAT (DEFAULT)
ONE ROW, THREE FOLDERS · THIS IS THE FLAT PACKAGE PRESENTATION — ECLIPSE'S DEFAULT
MAKE ECLIPSE TELL YOU THE TRUTH — SWITCH TO HIERARCHICAL, JUST ONCE
That single flat row is genuinely misleading while you are learning, because it looks like one folder named com.college.attendance — the exact wrong idea. Eclipse can show the nesting instead. Do this now:
Click the three vertical dots (⋮, View Menu) at the top-right corner of the Package Explorer panel → Package Presentation → Hierarchical.
The one row becomes three indented rows. Nothing on your disk changed; only the display did. That is the whole lesson: the flat row was always three folders. Leave it on Hierarchical for the rest of this course — when a package error appears, seeing the real nesting is what lets you spot the problem.
PACKAGE EXPLORER · HIERARCHICAL
MENU PATH · ⋮ View Menu › Package Presentation › Hierarchical · NOW THE INDENTATION MATCHES THE DISK
Step 4 · Now put a class inside it
Right-click on the package (com.college.attendance, or attendance if you switched to hierarchical) › New › Class. Right-clicking the package rather than src matters: it pre-fills the Package field for you, and a pre-filled field cannot be mistyped.
Java Class
Create a new Java class.
TICK public static void main(String[] args) SO WE CAN RUN THIS CLASS DIRECTLY · IN LAB 3 THE CALCULATOR WILL NOT HAVE A main — A SEPARATE Main CLASS IN com.college.app WILL DRIVE IT
package com.college.attendance;. You did not type it. Eclipse knew the package because you right-clicked on it, and it will keep that line correct even if you later drag the file to a different package. This is the single biggest practical reason to use an IDE for packaged code — the commonest package bug in the world is a package line that disagrees with the folder, and Eclipse simply does not let it happen.
Step 5 · Type the class and run it
A small, honest class: the attendance percentage rule that Vasavi actually applies. It also prints its own fully qualified name, so the run proves the package is real rather than us claiming it.
package com.college.attendance;public class AttendanceCalculator{ public double computePercentage(int attended, int total) { return attended * 100.0 / total; } public static void main(String[] args) { AttendanceCalculator calc = new AttendanceCalculator(); double pct = calc.computePercentage(42, 50); System.out.println("Attended 42 of 50 classes"); System.out.println("Attendance = " + pct + " %"); System.out.println("This class is really called:"); System.out.println(calc.getClass().getName()); }}AttendanceCalculator on line 3 and com.college.attendance on line 1, and Java joined them. That joined form is the class's real identity, and it is what the JVM used to find and load it.84.0 and not 84? Line 7 divides by 100.0, a double, so the whole expression becomes a double (Class 4). Writing attended * 100 / total with integers would give 84 here but 0 for 3 out of 4 classes — integer division truncates. The 100.0 is deliberate, and it is the same trick Lab 3 requires.
getClass().getName() returns the fully qualified name of an object's actual class. When a program in a real project says “class not found” or picks the wrong class of two same-named ones, this one line tells you which class you truly have. We will use it again in Unit III.
Step 6 · Now prove it — open the folder yourself
Do not take Eclipse's word for any of this. Minimise Eclipse, open File Explorer, and walk to your workspace. In Eclipse you can jump straight there: right-click the project › Show In › System Explorer.
THREE REAL FOLDERS, TWICE OVER · src\com\college\attendance HOLDS YOUR SOURCE · bin\com\college\attendance HOLDS THE COMPILED CLASS · THE PACKAGE STRUCTURE IS MIRRORED IN BOTH
FOUR THINGS TO NOTICE IN THAT WINDOW
1. There is no folder called “com.college.attendance”. There is com, and inside it college, and inside that attendance. Exactly as Part 7's diagram promised. If you had made one dotted folder by hand, the JVM would look for com\college\attendance\, fail to find it, and report Could not find or load main class.
2. There are two trees, not one. src holds .java files — the text you write. bin holds .class files — the bytecode javac produced. Eclipse compiles automatically on every save, which is why bin filled itself without you asking. This is exactly what javac -d does by hand in Part 9.
3. The package structure is repeated inside bin. It has to be. The package is part of the class's name, so the compiled file must be filed under the matching path or the JVM cannot find it.
4. You never see bin in the Package Explorer. Eclipse hides it deliberately, because you should never edit it — it is regenerated on every save. That hiding is also why so many Eclipse users have never seen a .class file. You just have.
Break the mirror on purpose, then fix it
1. In Eclipse, in the Package Explorer, drag AttendanceCalculator.java out of com.college.attendance and drop it onto src (the default package).
2. Open the file. Eclipse has quietly deleted line 1 for you — the package statement is gone, because the file is no longer in that folder. The IDE keeps the mirror intact automatically.
3. Now type package com.college.attendance; back in as line 1, by hand, and save. Instant red error on line 1: The declared package “com.college.attendance” does not match the expected package “”.
4. Read that message slowly. It is the mirror rule speaking: the package line says one address, the folder says another, and Java refuses to guess. Hover the error and Eclipse offers you both repairs — Move file to package com.college.attendance, or Remove package declaration. Choose the first, and everything is well again.
That error message is the one you will meet in Part 12's activity, on a machine where nobody is offering to fix it for you. Meeting it here, on purpose, with the cause fresh in your mind, is worth ten minutes of debugging later.
javac -d . and java com.college.attendance.AttendanceCalculator typed out by hand. Every folder will be one you created and every path one you can see. That is the version that makes packages permanent.
Building a package by hand
Now we do exactly what Part 8 did — same package, same class, same output — with Eclipse closed. You will create the three folders yourself with mkdir, type the file in Notepad++, compile with javac -d . and run with the fully qualified name. Nothing will be hidden, and by the end of this part the sentence “the package name mirrors the directory structure” will not be something you memorised. It will be something you did with your own hands.
Why we deliberately drop the IDE for this one part. Eclipse is genuinely excellent at packages — it made the folders, wrote the package line, compiled on save, and set the classpath, all without telling you. That is perfect when you already understand packages and a problem while you are learning them, because four different things happened and you performed none of them.
So here every step is yours. Notepad++ is a plain text editor: no auto-complete, no error markers, no helpful rewriting — it types exactly what you type. The terminal shows you the folder you are standing in and the precise command that ran. When a package goes wrong in the lab exam, this is the mental model that lets you fix it in thirty seconds instead of guessing.
And then we go straight back to Eclipse. Lab 3, and everything after it, is Eclipse work. This part is a one-time look under the bonnet — the most valuable twenty minutes in Unit II.
Step 1 · Make the folder tree with your own hands
Open Command Prompt (press Windows key, type cmd, press Enter). We start where we always start — the practice root you have been growing since Lab 0 — and make today's folder inside it.
javac -d . will treat “here” as the top of the package tree, and “here” means whatever the prompt says.Now the new part. We need the three nested folders com → college → attendance. On Windows, mkdir creates every missing folder in a path in one go, so one command is enough:
tree /f output carefully — it is the whole lesson in five lines. dir /b showed only one item, com, because the other two are inside it. tree /f shows the nesting. There is no folder anywhere called com.college.attendance.The slashes lean the other way and you need one extra flag:
mkdir -p com/college/attendance
The -p means “create parent folders as needed”. Without it, mkdir refuses because com does not exist yet. Windows mkdir does this automatically, which is why the Windows line has no flag. To view the tree, use find . or ls -R.
Every year students create one folder named com.college.attendance — by right-clicking in File Explorer and typing the dotted name. It looks identical in the address bar and it is completely wrong.
The JVM will search for com\college\attendance\ and find nothing, then report Could not find or load main class — an error that says nothing about folders and sends beginners hunting for imaginary bugs in their code. Type the mkdir command and it cannot happen.
Step 2 · Type the class in Notepad++
Open Notepad++. Type the program below — the same AttendanceCalculator from Part 8, so you can compare the two routes fairly. Line 1 is the line you must not forget, because unlike Eclipse, nothing here will write it for you.
NOTEPAD++ TYPES EXACTLY WHAT YOU TYPE · NO AUTO-COMPLETE, NO SILENT HELP · NOTICE THE TAB TITLE IS STILL RED/UNSAVED — SAVING IT CORRECTLY IS THE NEXT STEP, AND IT HAS ONE TRAP
THE NOTEPAD++ SAVE TRAP — READ BEFORE YOU PRESS CTRL+S
Press Ctrl + S. In the Save As dialog you must get two things right, and beginners miss the second one:
1 · The folder. Navigate all the way into Desktop\java-practice\class-16\com\college\attendance. Not class-16. Not com. The innermost folder — the one whose name matches the last part of the package.
2 · The file type. Set Save as type to All types (*.*) and type the name as AttendanceCalculator.java. If you leave the type as Normal text file (*.txt), Windows silently saves AttendanceCalculator.java.txt — and because File Explorer hides known extensions by default, it will still look like AttendanceCalculator.java on screen. Then javac reports file not found for a file you can plainly see, and you lose twenty minutes.
How to be certain: back in the terminal run dir com\college\attendance. The real, complete filename is printed there, with no extension hiding. If it says .java.txt, rename it: ren AttendanceCalculator.java.txt AttendanceCalculator.java.
Step 3 · Understand javac -d . before you type it
Since Class 2 you have compiled with a bare javac Something.java, which drops the .class file right beside the source. That is fine for a class with no package. For a packaged class it is not fine, because the .class file has to end up in a folder tree matching the package — and -d is the flag that makes javac build that tree for you.
THE COMMAND, TAKEN APART
| Piece | What it is | What it does here |
|---|---|---|
javac | The Java compiler (Class 2) | Turns .java source text into .class bytecode. |
-d | An option — short for destination | Tells the compiler where to put the output, and to create the package folders itself under that place. Without -d the .class lands beside the source with no tree at all. |
. | The value given to -d — a single dot | The dot means “the folder I am standing in right now”. So the package tree is built starting from the current folder. Stand somewhere else and it builds somewhere else. |
com\college\attendance\ | The source file to compile | Just a path to the input. It is where the file is, and has nothing to do with where the output goes — that is -d's job alone. |
THE ONE SENTENCE THAT STOPS ALL -d CONFUSION
-d says where the output tree begins. The filename at the end says where the input is. They are two independent things.
Beginners assume the two must match, then panic when a command has com\college\attendance in it twice, or once, or not at all. Once you separate input from output, every variant makes sense — including the shortcut we look at in a moment, where the source sits at the root and javac still files the output three folders deep.
Step 4 · Compile, then run by fully qualified name
Four commands, in the terminal, standing at the project root (class-16). Nothing else. This is the terminal truth — exactly what appears on a real machine.
84.0, same fully qualified name. Eclipse was running these exact two commands for you all along, on every save and every click of the green arrow. You have just done its job manually.LOOK HARD AT COMMAND 4 — THREE THINGS ARE HAPPENING
1 · Dots, not slashes. You typed java com.college.attendance.AttendanceCalculator — a class name, not a file path. There is no \ and no .class. The launcher takes that name, turns the dots into folder separators itself, and looks for com\college\attendance\AttendanceCalculator.class.
2 · It searched from where you are standing. Nothing in command 4 said where to look. The JVM's default classpath is the current folder, and the current folder is class-16, which is exactly the root of the tree -d . built. That agreement between “where -d put things” and “where java looks” is why it works — and Part 11's self-study on the classpath is about controlling it.
3 · You never mentioned the .java file. The compiler consumed the source; the JVM only ever sees bytecode. Two separate tools, two separate inputs — the javac-then-java pairing you have used since Class 2, now with a package in the middle.
And the disk, checked from outside, matches exactly what Eclipse produced in Part 8 — because Eclipse was doing this:
SOURCE AND BYTECODE SIDE BY SIDE IN THE SAME MIRRORED TREE · ECLIPSE SPLIT THEM INTO src\ AND bin\; BY HAND THEY SIT TOGETHER — BOTH ARRANGEMENTS ARE FINE, BECAUSE THE ONLY THING THAT MATTERS IS THAT THE .class FILE'S PATH MATCHES ITS PACKAGE
A second route — let javac build the folders for you
Here is something that surprises almost everybody, and it is the clearest possible proof that -d controls the output only. You do not actually have to create the folders at all. Watch: we start a completely empty folder, put the source file loose at the top, and compile.
mkdir com\college\attendance, and yet there it is. The compiler read line 1 of the source, saw package com.college.attendance;, and because -d . told it to build a tree here, it created all three folders and filed the bytecode at the bottom. It runs identically.Route A — source inside the mirrored folders — is what every real project does, and it is what Eclipse does with its src tree. Use it for Lab 3 and beyond, because a project with 40 classes needs its source organised too, not just its bytecode.
Route B is a handy trick for a single throwaway file, and a superb teaching demonstration. Now you know the compiler reads the package line and acts on it, rather than merely recording it.
Route B works because javac does not require the source file to sit in a matching folder — only the output must match. Eclipse is stricter than the compiler here, and flags a mismatch as an error immediately.
That means on the command line a badly filed source file can compile without complaint and then fail confusingly at run time. This is the exact situation in Part 12's error-detection activity — and it is a real reason to prefer the IDE once you understand what it is protecting you from.
The three errors everyone hits — with the real messages
Read these now, while the machinery is fresh. In the lab exam these three messages account for nearly every package problem, and each has a one-line cause.
attendance, the JVM searches for attendance\com\college\attendance\... — the tree repeated inside itself. Fix: cd ..\..\.. back to the project root and run it again. Rule: always run java from the folder that contains com, never from inside the package..classAttendanceCalculator anywhere — there is one called com.college.attendance.AttendanceCalculator. Cause of the second. java takes a class name, never a filename, so appending .class makes it hunt for a class literally named class inside a package ending ...AttendanceCalculator. Fix for both: full dotted name, no extension.-d, the .class file was written beside the source, in com\college\wifi\ — a path that does not match the package recorded inside it, so the JVM cannot find it under the name it advertises. Fix: either move the file into com\college\attendance\, or change line 1 to package com.college.wifi;. Make the two agree — and always compile with -d ., which files the output correctly whatever the source path. This is Part 12's activity in a nutshell.Eclipse and the command line, side by side
You have now built the same package twice, two ways. Here is what each step actually was, in both worlds. Read the middle column once and Eclipse stops being magic.
| The job | By hand (Part 9) | In Eclipse (Part 8) |
|---|---|---|
| Make the project | mkdir class-16 and cd into it | File › New › Java Project |
| Make the package folders | mkdir com\college\attendance | Right-click src › New › Package, one dotted name |
Write the package line | You type it, and you own the mistake | Written for you, and kept correct if you move the file |
| Compile | javac -d . <path>\File.java | Happens automatically on every Ctrl + S |
| Where the bytecode goes | Wherever -d says — here, beside the source | Into the hidden bin\ tree |
| Run | java com.college.attendance.AttendanceCalculator from the root | Green ▶ arrow, or Ctrl + F11 |
| Classpath | Defaults to the current folder — so where you stand matters | Eclipse sets it to bin\ and you never think about it |
| Mismatched package vs folder | Compiles quietly, then fails at run time | Red error on line 1 the instant you save |
The last row is the whole argument for using an IDE — but only now that you know what it is protecting you from.
import, the last piece of syllabus machinery in Unit II's fifth item — and it is the exact tool Lab 3's Main class needs in order to reach AttendanceCalculator across a package boundary. Part 10, next.
import — the short name, borrowed
You have written import before. In Class 6 you typed import java.util.Scanner; because the notes said to, and it worked, and we moved on. That was a promise deferred. Today you know what a package is, so the promise can be kept: in the next ten minutes import will stop being a magic word at the top of a file and become an obvious, almost boring convenience — one you will need in Lab 3, Exercise 2, where Main must reach across a package boundary to use your calculator.
Step 1 · The problem — long names everywhere
Part 9 ended with a class whose real name is com.college.attendance.AttendanceCalculator. Now write the driver: a separate class, in a different package, that uses it. This is precisely Lab 3's shape, so look carefully.
import — there is no second, deeper purpose. THE MISCONCEPTION TO KILL RIGHT NOW — import DOES NOT COPY CODE
Almost every beginner believes import pulls the other class's code into your file, the way #include does in C. It does not. Nothing is copied, nothing is loaded, and your .class file does not grow by a single byte.
import is purely a note to the compiler about names. It says: “in this file, whenever I write the short word AttendanceCalculator, I mean the one in com.college.attendance.” That is all. It is a spelling shortcut, resolved at compile time and then gone.
The proof: the two programs above produce byte-for-byte identical bytecode. If you inspect the compiled Main.class, the fully qualified name is what is stored inside it, in both cases. The short form never existed anywhere but in your source text. So import costs nothing at run time, and importing something you do not use costs nothing either.
Step 2 · The term, properly
An import statement lets you refer to a class from another package by its short name. It grants no permission and gives no access — whether you are allowed to use a class is decided entirely by public and the access table from Part 7. import only decides what you are allowed to call it.
At the start of a group project you say once: “when I say Ramesh, I mean Ramesh Kumar from CSE-B, not the other two Rameshes.” After that one sentence you say “Ramesh” for the rest of the meeting and everyone knows who you mean.
You did not bring Ramesh into the room. You did not gain any authority over him. You declared a short form. If a second Ramesh joins the project you must go back to using full names for at least one of them — which is exactly what happens with the java.util.Date / java.sql.Date clash we meet in a moment.
Every import sits after the package line and before the first class. There is no limit on how many you write. Order among them does not matter.
package com.college.app;
import com.college.attendance.AttendanceCalculator; // single class
import java.util.*; // wildcard — whole package
public class Main
The fixed order is: package, then imports, then classes. Put an import above the package line and the compiler stops you at once — and the message is unhelpfully generic (Syntax error on token “import”), so learn the order rather than the error.
Single-class import — import com.college.attendance.AttendanceCalculator; — names exactly one class. Precise, self-documenting, and what professional code and every IDE prefers.
Wildcard import — import java.util.*; — makes every public class in that one package available by short name. The * is not a filename pattern and it is not recursive: java.util.* does not include java.util.concurrent, because that is a different package that merely sits inside the same folder. This surprises people, and it follows directly from Part 7 — a package is one folder level, not a subtree.
When the compiler meets a bare type name such as AttendanceCalculator, it resolves it by walking a fixed search order:
(a) Is it declared in this same file? (b) Is it in the same package as this file? (c) Is it named by a single-class import? (d) Is it in any wildcard-imported package, or in java.lang? (e) Otherwise — cannot be resolved to a type.
Two consequences worth knowing. First, a single-class import always wins over a wildcard, which is the standard fix for an ambiguity. Second, if two wildcards both offer the same short name, the compiler will not choose — it reports the ambiguity and makes you decide, which is the behaviour we deliberately trigger below.
System, String, Object, Integer, Math, Exception, Thread — you have used all of these since Class 3 and never imported one. They all live in java.lang, and the compiler imports java.lang.* into every file automatically. It is so fundamental that Java does it for you.
So System.out.println is really java.lang.System.out.println, and String is really java.lang.String. Writing import java.lang.*; yourself is perfectly legal and completely redundant. This is a favourite one-mark exam question: which package is imported by default in every Java program? Answer: java.lang.
Three cases, and knowing them prevents a lot of pointless typing:
(a) Same package. Classes in the same package see each other by short name automatically. In Lab 3 your Main needs an import because it is in com.college.app while the calculator is in com.college.attendance. Put both in one package and no import is needed — but then you lose the two-package structure the lab is teaching.
(b) java.lang. Automatic, as above.
(c) You wrote the fully qualified name. The long name always works, import or not — and it is the only way to use two same-named classes in one file.
Step 3 · A real two-package program — your Lab 3 rehearsal
Back to Eclipse for this. We keep com.college.attendance.AttendanceCalculator from Part 8 and add a second package with a driver in it. This is the exact structure of Lab 3, at a smaller size, so that the lab is a repetition rather than a first attempt.
First make the second package: right-click src › New › Package › name it com.college.app › Finish. Then right-click that package › New › Class › name Main › tick public static void main › Finish.
PACKAGE EXPLORER · HIERARCHICAL
TWO PACKAGES, SIDE BY SIDE UNDER college · attendance HOLDS THE LOGIC, app HOLDS THE ENTRY POINT — THE SAME SPLIT REAL PROJECTS USE, AND THE SPLIT LAB 3 REQUIRES
package com.college.app;import com.college.attendance.AttendanceCalculator;public class Main{ public static void main(String[] args) { AttendanceCalculator calc = new AttendanceCalculator(); String[] names = { "Diya Sharma", "Aarav Reddy", "Sneha Iyer" }; int[] present = { 42, 30, 48 }; int total = 50; System.out.println("ATTENDANCE REPORT — total classes held: " + total); for (int i = 0; i < names.length; i++) { double pct = calc.computePercentage(present[i], total); System.out.println(names[i] + " -> " + pct + " %"); } System.out.println("Calculator used: " + calc.getClass().getName()); System.out.println("Driver is: " + Main.class.getName()); }}import line. That is the whole of Lab 3's architecture, proven in one console.public matters here, exactly as Part 7 warned. AttendanceCalculator is public, and computePercentage is public. Remove either keyword and line 9 or line 19 fails — The type AttendanceCalculator is not visible or The method computePercentage(int, int) is not visible. The import would still be perfectly correct: an import is not permission.
Main.class.getName(). A small piece of new syntax: for a class (not an object) you write ClassName.class to get its class information. We use it here because main is static and there is no Main object to ask. It confirms the driver's own address.
for loop on lines 17–18 is a block, so its { gets its own line.
isDetained(double), which is yours to write in Lab 3, Exercise 1. Today's job was the plumbing across packages; the rule comes next session.
THE SAME PROGRAM ON THE COMMAND LINE — SO YOU CAN DO IT EITHER WAY
Two packages compile in one command: list both sources, and -d . files each .class under its own package. Then run the class that has main, by its full name.
C:\...\class-16> javac -d . com\college\attendance\AttendanceCalculator.java com\college\app\Main.java
C:\...\class-16> java com.college.app.Main
Compile Main.java alone and it still works, because javac follows the import, finds the calculator's source on the classpath and compiles it too. Worth knowing, but list both files — being explicit costs nothing and removes all doubt.
Beyond the usual example — when import cannot help you
Everything so far said import is a harmless convenience. Now the one situation where it runs out of road — and it is the situation that explains why packages exist at all, so it is worth its own program.
Java's library has two classes called Date: java.util.Date (a date and time) and java.sql.Date (a database date). Ask for both by wildcard and watch the compiler refuse to guess.
Date line:The type Date is ambiguous
Two wildcards, two candidates, no rule to pick between them. The compiler will not choose for you — silently guessing would be far worse than complaining.
package com.college.app;// No import at all — every name below is written in full,// which is the ONLY way to use both Date classes here.public class TwoDatesDemo{ public static void main(String[] args) { java.util.Date rightNow = new java.util.Date(); java.sql.Date joinedOn = java.sql.Date.valueOf("2024-08-01"); System.out.println("util.Date shows date AND time:"); System.out.println(" " + rightNow); System.out.println("sql.Date shows the date only:"); System.out.println(" " + joinedOn); System.out.println("Same short name, different classes:"); System.out.println(" " + rightNow.getClass().getName()); System.out.println(" " + joinedOn.getClass().getName()); }}Date, alive in the same program at the same time. Without packages, one of them could not exist. This is Part 7's opening problem, solved.java.util.Date is a moment in time, so it prints day, time and zone. java.sql.Date exists to map onto a database DATE column, which has no time part, so it prints the plain yyyy-MM-dd form. Confusing these two is a genuine bug in real projects, and it happens precisely when someone lets a wildcard import choose for them.
java.util.Date properly later. Unit IV uses java.util heavily for collections. Today it is only here as the clearest same-name pair in the whole Java library.
Wildcard or single class? — settled
| Question students ask | The honest answer |
|---|---|
Is import java.util.*; slower at run time? | No. Not by any measurable amount, ever. Imports are resolved at compile time and vanish; the bytecode is identical. The old belief that wildcards “load the whole package” is simply false — nothing is loaded until a class is actually used. |
Does it make the .class file bigger? | No. Only names you truly use appear in the bytecode. |
| So why does everyone prefer single-class imports? | Readability and safety. A reader can see exactly which classes a file depends on, and an ambiguity like Date becomes impossible. It also survives library upgrades: if a future version of a package adds a class named like one of yours, a wildcard can start an ambiguity in code you never touched. |
| Do I have to type those long lines myself? | No — and you should not. In Eclipse press Ctrl + Shift + O ("Organize Imports") and it adds every import your file needs and deletes the unused ones. If two classes clash, it shows you a chooser. Use the short name first, then Ctrl + Shift + O. |
What about import static? | A Java 5 variant that imports a member, letting you write sqrt(x) instead of Math.sqrt(x). Real, occasionally useful, and outside this syllabus — mentioned so the phrase is not a mystery if you meet it online. |
LEARN THESE SENTENCES · THE EXAM ASKS FOR THEM ALMOST WORD FOR WORD
“A package is a named grouping of related classes and interfaces which provides a namespace, an additional level of access protection, and easier organisation and distribution of code. The package name must mirror the directory structure on disk, and it is declared as the first statement of the source file. The import statement allows classes of another package to be referred to by their simple name instead of their fully qualified name; java.lang is imported into every program automatically.”
Add the one-line distinction and you cover every variant of the question: “package declares where a class lives; import declares what a class may be called. Neither grants access — that is what public is for.”
FIVE import ERRORS, WITH THEIR REAL MESSAGES
1 · Import above the package line. Syntax error on token “import”. Order is fixed: package, imports, classes.
2 · Importing a package as if it were a class — import com.college.attendance; with no class name and no *. Real message: The import com.college.attendance cannot be resolved. Either name the class or add .*.
3 · Expecting the wildcard to reach subpackages. import com.college.*; does not give you com.college.attendance.AttendanceCalculator. You get AttendanceCalculator cannot be resolved to a type. One wildcard, one package level.
4 · Importing a non-public class from another package. The import line itself goes red: The type AttendanceCalculator is not visible. The class is there and correctly named — it simply is not public. Import is not permission.
5 · Importing a class in your own package. Harmless, unnecessary, and Eclipse greys it out as an unused or redundant import. Classes in the same package already see each other.
Classpath — the list of places
Java is willing to look
SELF-STUDY PART — READ THIS ONE ON YOUR OWN
Short, complete, and on this page — nothing here is heavily examined
The classpath is not a line in the syllabus sentence, so the course marks it self-study. It is here in full for two reasons. First, it is the answer to a question Part 9 deliberately left hanging. Second, when a package error confuses your classmates in Lab 3, this page is why it will not confuse you. Read it once tonight. You do not need to memorise any flag.
Step 1 · The question Part 9 left open
In Part 9 you typed this and it worked:
C:\Users\student\Desktop\java-practice\class-16\com\college\attendance\AttendanceCalculator.class?Because it had a starting point. The dotted name gives Java the route — three folders down, then a file. But a route needs somewhere to start walking from. That starting point is the classpath.
The classpath is the list of starting folders (and .jar files) that the JVM and the compiler are allowed to search when they need to find a class. Nothing more mysterious than that: a list of places.
The package name says where inside a starting folder the class sits. The classpath says which starting folders exist. You need both halves before a class can be found.
Think of the Vasavi campus. Someone hands you a slip that reads Block B, second floor, room 204. That slip is a perfectly good route — but only if you already know which campus to enter. Standing outside a different college, the same slip finds nothing.
The dotted class name is the slip: com.college.attendance.AttendanceCalculator. The classpath is the list of campus gates you are permitted to walk in through. Java takes gate one, follows the slip, and if there is no such room it goes to gate two, and so on. When every gate has been tried, it gives up — and that giving up is the message you have already met: Could not find or load main class.
Step 2 · Why Part 9 worked without you setting anything
You never set a classpath in Part 9. You did not have to, because of one rule worth remembering:
THE ONE SENTENCE TO CARRY AWAY
If you do not specify a classpath, the classpath is a single entry: the folder you are currently standing in. That is why cd mattered so much in Part 9 — changing folders was silently changing the classpath.
Now every Part 9 error makes sense in one sentence each:
THE THREE PART-9 ERRORS, RE-READ THROUGH THE CLASSPATH
| WHAT YOU DID | THE CLASSPATH WAS | WHY IT FAILED OR WORKED |
|---|---|---|
Ran from class-16 | class-16 | Worked. Starting folder + route com\college\attendance = the real file. |
Ran from inside attendance | ...\com\college\attendance | Failed. Java looked for attendance\com\college\attendance\..., which does not exist. The route was applied from the wrong gate. |
Compiled without -d | the source folder | Failed at run time. The .class landed beside the source instead of at the top of a matching tree, so the route pointed at nothing. |
Read the table once more and notice that not one of those three failures was a Java-language mistake. The code was fine every time. All three were disagreements between the route (the package name) and the gate (the classpath). That is the single most common category of beginner package error, and it is why this page exists.
Step 3 · Saying it out loud with -cp
You can name the starting folder instead of relying on where you happen to be standing. The flag is -cp (or its longer twin -classpath). Try this from anywhere at all — even from your Desktop:
Desktop, and Desktop\com\college\attendance\ does not exist.LOOK AT THE SHAPE OF THAT COMMAND
java -cp where to start looking dotted route from there
The two parts never overlap. -cp uses real folder separators (\ on Windows, / on macOS and Linux) because it is a path on your disk. The class name uses dots because it is a Java name. Mixing the two up produces most classpath frustration: java -cp . com/college/attendance/AttendanceCalculator will be rejected, and java -cp com.college.attendance Main looks for a folder literally named com.college.attendance.
The classpath is a list, so it can hold several entries. The separator is a semicolon on Windows and a colon on macOS and Linux:
java -cp bin;libs\opencsv.jar com.college.app.Main
Java tries each entry left to right and stops at the first match. A .jar file counts as one entry, because a jar is a zipped folder tree of packages — which is exactly why packages make libraries distributable, the fourth advantage from Part 7.
CLASSPATH environment variable — don't
Windows lets you set a permanent system variable named CLASSPATH. Old tutorials tell you to. Please do not. It applies to every Java program on the machine forever, it silently overrides the “current folder” default, and the resulting failures are almost impossible for a beginner to diagnose.
If a stale CLASSPATH is already set on a lab machine and a working command suddenly stops working, the rescue is to end it with a dot: java -cp . MyClass puts the current folder back on the list explicitly.
Step 4 · What Eclipse has been doing for you all along
You have never typed -cp in Eclipse and never will in this course. Eclipse maintains the classpath for every project as a file, and you have already seen that file — in Part 8's File Explorer window, sitting quietly beside src and bin.
TICK View › Show › Hidden items IN FILE EXPLORER IF THE DOT-FILES ARE NOT VISIBLE
Inside, in plain XML, it says two things you can now read for yourself: source lives in src, and compiled output goes to bin. That second line is Eclipse doing your javac -d bin silently, on every single save. When you press Run, Eclipse builds a java -cp bin com.college.app.Main for you and runs it.
.java lives) · Libraries (the JRE, plus any .jar you add) · Order and Export (the left-to-right search order from Step 3)Step 5 · What to keep, and what to forget
1. The classpath is the list of starting folders Java searches; the package name is the route inside one of them.
2. With no classpath given, the list is just the folder you are standing in — so cd changes it.
3. Could not find or load main class almost always means route and gate disagree, not that your code is wrong.
The exact separator characters, the CLASSPATH variable, wildcard entries such as -cp "libs/*", and every classpath-related flag beyond -cp. Look them up the day you need them.
Also outside this course: modules and module-path, the Java-9 successor to all of this. That is why Part 8 told you to leave module-info.java un-ticked.
package line and whose folder do not agree. Have your notebook open; write your answer down before you unlock anything.
Find the fault: the line says one thing,
the folder says another
Ten minutes, in your notebook, on your own. This is not a quiz on syntax — every character of the Java below is legal. The fault is in the relationship between the code and the disk, which is the only genuinely new idea in Class 16 and the one that will cost your classmates time in Lab 3.
The scenario
A student is building the campus app. Yesterday she made a package for the Wi-Fi module, com.college.wifi. Today she needs the attendance calculator, so she right-clicked the existing wifi package, chose New › Class, named it AttendanceCalculator, and then hand-edited line 1 to say what she thought it should say.
PACKAGE EXPLORER · FLAT
ONE CLASS, TWO CONTRADICTORY STATEMENTS ABOUT ITS ADDRESS · THE TREE SAYS com.college.wifi · LINE 1 SAYS com.college.attendance
package com.college.attendance;public class AttendanceCalculator{ public double computePercentage(int attended, int total) { return attended * 100.0 / total; } public static void main(String[] args) { AttendanceCalculator calc = new AttendanceCalculator(); System.out.println("Attendance = " + calc.computePercentage(42, 50) + " %"); }}YOUR TASK Write all five answers in your notebook before unlocking anything. Guessing and then reading is how this activity stops working.
- Name the fault in one sentence. Not “line 1 is wrong” — say precisely what disagrees with what.
- Write the compiler message you expect, as closely as you can. You have seen it once already in this class, in Part 8's break-the-mirror experiment.
- Is this a compile-time error or a run-time error? Justify it. Then answer the harder half: would the plain command-line tool
javacalso refuse it? (Part 9 answered this. It is not the answer most students give.) - Give two different fixes — one that keeps line 1 and one that keeps the folder. State what each fix implies for the rest of the project.
- Which fix should she choose here, given she is building the Lab 3 attendance app, and why?
BONUS She wonders whether she can dodge the whole problem by deleting line 1 entirely. Say what happens if she does, and why it is a bad idea in a project that already has a com.college.wifi package.
Five answers in the notebook first — then unlock.
1 · The fault, in one sentence. Line 1 declares the class to be in com.college.attendance, but the file physically sits in src\com\college\wifi\. The package declaration and the folder path do not mirror each other, and Java requires that they do — because, as Part 7 put it, the package name is the search path.
2 · The compiler message. Eclipse flags line 1 itself, with a red marker in the margin:
src downwards. Once you know that, the message tells you both the wrong value and the right one, and you can fix it without thinking.If instead she had dragged the file out to src directly, the same message would read does not match the expected package "" — an empty string, meaning the default package. That is the exact wording from Part 8, and it is the same fault with a different “expected” value.
3 · Compile time or run time — and would javac agree?
Compile-time error. Eclipse checks the source folder layout against the package line on every save and refuses to produce a usable .class. You cannot even reach the run stage. Pressing Run gets you the “Errors exist in the project” dialog you first met in Lab 2.
This is the half most students get wrong. Plain javac is laxer than Eclipse: javac com\college\wifi\AttendanceCalculator.java compiles quietly, with no error, because javac is compiling a file you named, not policing a project layout. The mismatch surfaces later as
Error: Could not find or load main class com.college.attendance.AttendanceCalculator
Which is exactly Part 9's ERROR 3. Eclipse is stricter on purpose — it converts a confusing run-time failure into an obvious red line at the point where you can still see the cause.
THE HONEST VERSION OF THE ANSWER
“Compile-time in Eclipse; on the command line javac -d . would place the output under com\college\attendance\ as line 1 asks, the source's own folder is ignored, and the failure only appears when something looks for the class where the source lived.” If you wrote that, you have understood Parts 8, 9 and 11 as one idea rather than three pages.
4 · Two fixes. Both are correct Java. They mean different things about the project.
Keep line 1, move the file. Create the package the line asks for and move the class into it. In Eclipse: right-click src › New › Package › com.college.attendance, then drag AttendanceCalculator.java onto the new package (or select it and press Alt + Shift + V, the Move refactoring). The red marker clears the moment the file lands.
Implication: the project now has two sibling packages, com.college.wifi and com.college.attendance, which is a clean separation — Wi-Fi code and attendance code have no business in one folder. Any other class that referred to it will need import com.college.attendance.AttendanceCalculator;.
Keep the folder, change line 1. Edit line 1 to package com.college.wifi;. The error clears immediately, because now the declaration matches the folder.
Implication: the attendance calculator is now permanently filed under the Wi-Fi module. It compiles. It runs. It is bad filing — you have just put the fees register in the Wi-Fi cupboard. Six months later nobody finds it. The compiler is satisfied and the project is worse.
ECLIPSE OFFERS YOU BOTH, AND NOW YOU CAN CHOOSE
Hover the red marker on line 1 and Eclipse shows two quick-fixes: “Move AttendanceCalculator.java to package com.college.attendance” (Fix A) and “Change package declaration to com.college.wifi” (Fix B). Students click whichever is on top and hope. You are not doing that any more — the first fix moves a file, the second re-files a module, and you know which you meant.
5 · Which fix here? Fix A. She is building the attendance feature of the Lab 3 app, whose locked layout is com.college.attendance.AttendanceCalculator plus com.college.app.Main. Fix B would compile and then have her importing an attendance class out of a Wi-Fi package for the rest of the lab — every reader of that code, including her in a week, would be misled. The package name is documentation the compiler happens to enforce; pick the honest one.
BONUS — WHAT IF SHE JUST DELETES LINE 1?
Then Eclipse reports the mirror image of the same fault: The declared package "" does not match the expected package "com.college.wifi". Deleting the line does not put the class in “no package” — the class is still sitting in com\college\wifi\, and the folder wins the argument about what is expected.
To genuinely have no package she would also have to drag the file up to src. And that is a bad idea anyway: the project already has com.college.wifi, so she would be mixing packaged and unpackaged classes in one project — and a class in the default package cannot be imported by a packaged class at all. Her Wi-Fi classes would be unable to use the calculator, with no import that could rescue them. This is why real projects put every class in a package.
THE MARKING SCHEME, IF THIS WERE ASKED FOR 4 MARKS
- 1 MARK Identify that the
packagedeclaration and the directory path disagree — naming both values. - 1 MARK Quote or paraphrase The declared package ... does not match the expected package ... and classify it as a compile-time error.
- 1 MARK Give the fix: move the file into
src\com\college\attendance\, or amend the declaration to match the folder. - 1 MARK State the general rule: the package name must mirror the folder path exactly, from the source root downwards.
IF YOU ANSWERED “AttendanceCalculator CANNOT BE RESOLVED”
That is a different error and it is worth separating the two now, tonight, before Lab 3. Cannot be resolved to a type means Java could not find a class of that name at all — wrong or missing import, typo, or not on the classpath. Does not match the expected package means Java found the file perfectly well and objects to where it is filed. The first is “who?”; the second is “why are you here?”
collage for college, or a capital College. Package names are case-sensitive.
You have been reading package names
for years without noticing
This activity needs no computer. It needs the phone in your pocket. Everything you learned in Part 7 about reverse-domain naming is already printed on your own device, in several places, and once you have seen it there the convention stops being an exam rule and becomes something obviously sensible.
Where to look, on your own phone
Every Android app on earth has a package name, and Android calls it the application ID. It is the app's true, unique identity — two apps can both be called “Notes” on the Play Store, but no two apps may share a package name. Same problem you met in Part 7 with two teams both writing Library; same solution.
Settings › Apps › pick any app › App info › scroll to the bottom. Many phones print the package name there directly. On others, tap App details or the ⋮ menu.
Easier route, works everywhere: open play.google.com in a browser, search for the app, and look at the address bar. It ends in ?id=com.whatsapp. That id value is the package name.
Apple calls the same thing a bundle identifier and uses the identical reverse-domain convention — com.apple.mobilesafari, net.whatsapp.WhatsApp. It is not visible in Settings, so use the Play Store web trick above; every popular app is on both stores with near-identical naming.
No device handy? The four names in the table below are real and are enough to complete the activity from your notebook.
Four real ones to start from
These are genuine, current package names. Read each one right to left, the way Part 7 taught you — widest thing first, most specific thing last.
Only two parts. Read backwards: the company whatsapp, inside the commercial namespace com. Their domain is whatsapp.com. Short, because the company name and the product name are the same thing.
Three parts, and the third one is not a product — it is a platform. Instagram ships an iOS app too, so they needed to distinguish. Domain: instagram.com.
Here the third part is the product. Spotify also publishes com.spotify.tv.android and com.spotify.lite — one company, one owned prefix, several apps hanging off it.
An Indian company, same convention. Domain byjus.com, then a product name that is simply the app's marketing name run together. Nothing is stopping you from doing exactly this.
WHAT THESE FOUR NAMES HAVE IN COMMON
Every one of them begins with a part the company owns and can prove it owns — a registered internet domain, reversed. Nobody else on the planet controls spotify.com, so nobody else may legitimately publish anything under com.spotify. That is the entire mechanism. There is no central Java registry, no committee, no application form. The convention borrows the uniqueness that the domain-name system already guarantees.
YOUR TASK Notebook, ten minutes, five short answers. Answers 1 and 2 need your own phone; the rest need only thinking.
- Find two package names yourself — one app made by a large global company, one made by an Indian company or your college/bank/transport app. Write them exactly as printed, including capitalisation.
- For each, split it into its parts and say what each part is doing. Which part is the reversed domain? Which part identifies the product or platform? Does one of yours have four parts?
- Why reversed? Answer the question directly: what would go wrong if Android used
whatsapp.com.someappinstead? Your Part 7 folder-tree picture is the answer — use it. - The uniqueness argument. Suppose two students in this class both write a chat app and both name the package
com.chat. Nothing crashes today. Explain in two sentences when it breaks and why reverse-domain naming would have prevented it. - Now name your own. Vasavi's domain is
vce.ac.in. Write the package name you should use for your Lab 3 attendance work if it were a real product of the college, and then write the package name for a hobby app you personally own the domain for — or, if you own no domain, look up what convention is recommended for that case.
BONUS One of these four is a real trap: com.byjus.thelearningapp runs three English words together with no separator. Say why the author did not write com.byjus.the-learning-app or com.byjus.theLearningApp, and which of those two is merely bad style versus outright illegal.
Two real names off your own phone first.
1 & 2 · Your two names. Yours will differ, so here are two worked examples — one global, one Indian — taken apart the way your answer should be.
com this is google.com spelled backwards — the part that guarantees uniqueness.com — a point worth making in your answer.npci.org.in. Reverse the whole domain, not just the last piece.com.whatsapp) and five parts are both legal.
3 · Why reversed? Because the name is a path, and a path must start at the widest container and narrow down — exactly like the postal address in Part 7, and exactly like the folders on your disk. The domain name system happens to be written the other way round: www.vce.ac.in narrows from right to left. Java and Android need it the other way, so they flip it.
The concrete consequence is the one you drew in Part 7. Reversed, the folder tree groups sensibly:
com, one google, one spotify. Related things share ancestors. Unrelated things never collide.com appears once per app, buried at the bottom of every branch, and Google's own two apps have nothing in common at the top level. The grouping is inside-out, the shared prefix is gone, and the uniqueness guarantee is stranded at the deepest folder where it protects nothing. The tree only works if the unique part comes first.4 · The uniqueness argument. Two com.chat apps are harmless while they live on two separate laptops. It breaks the moment they meet: publish both to the Play Store and the second upload is rejected outright, because the store enforces one app per package name globally. In Java the equivalent meeting is a shared classpath — put both jars on it and one class silently shadows the other, giving you an app that runs the wrong code with no error message at all, which is far worse than a rejection.
Reverse-domain naming prevents it without anyone coordinating: student A owns nothing, so she uses her college's name, in.ac.vce.students.arun.chat; student B does the same with his own identifier. The names cannot clash, because the domain names they are built from cannot clash.
5 · Naming your own.
- VCE PRODUCT The college domain is
vce.ac.in, so reversed it isin.ac.vce, and the attendance work becomesin.ac.vce.attendance. Note this course's teaching choice: Class 16 and Lab 3 use the shortercom.college.attendanceso that every screenshot, folder and command in the lab sheet stays readable. Real Vasavi software would use the reversed real domain. - YOUR OWN If you own
arunreddy.in, your hobby app isin.arunreddy.chatapp. - NO DOMAIN The recommended convention is to use a namespace you demonstrably control on a service you have an account with — commonly
io.github.<yourusername>for GitHub, orcom.examplefor throwaway teaching code.com.exampleis reserved by specification for exactly this and is guaranteed never to be a real company, which is why it appears in every tutorial. Never publish anything real under it.
BONUS — WHY thelearningapp AND NOT the-learning-app
Because each dot-separated part of a package name must be a legal Java identifier, and the rules are the same ones you learned for variable names back in Class 4. A hyphen is the subtraction operator, so com.byjus.the-learning-app is outright illegal — the compiler reads it as a subtraction inside a name and rejects the line.
com.byjus.theLearningApp is legal but poor style. It compiles and runs. The convention says package names are all lower case, for a very practical reason: package names become folder names, Windows folder names are case-insensitive while Linux folder names are not, and a project whose packages differ only by capitalisation will build on one machine and mysteriously fail on the other. All-lower-case makes the whole class of problem impossible.
And the three rules that come with it: no Java keyword may be a part — com.mycompany.new and com.mycompany.class are both illegal — no part may begin with a digit, so a company called 3M writes com._3m or com.threem, and no part may contain a space or a dash.
THE ONE THING TO CARRY OUT OF THIS ACTIVITY
Reverse-domain package naming is not a Java quirk you must memorise for four marks. It is how the entire software industry allocates unique names without a central authority — Java packages, Android application IDs, Apple bundle identifiers, Maven group IDs, and .NET namespaces all use the same trick, because it is the only one that scales to millions of independent authors who will never speak to each other.
You have been holding the evidence in your hand since the first day of this course.