Concepts / Public and Private Access in Java Classes

Public and Private Access in Java Classes

A static method is called from another class by writing the class name, a dot, and the method name: ClassName.methodName();

  • Programming

A Call That Looks Reasonable

Programs are usually split across several classes, and a method written in one class is often useful in another. Suppose a class named Poker contains a public static method called playGame(). Because the method is static, it belongs to the class itself rather than to any particular object created from it. The question this section raises is simple: when the code calling the method lives in a different class, how must the call be written so that Java finds the right method?

What do you think happens?

Main is a different class from Poker. Its main() method contains only the statement playGame(); with no class name in front. Does this compile and run?

  • It compiles and prints the output of Poker's playGame() method

  • It fails to compile

Reveal answer
Answer:

It fails to compile

A bare call such as playGame(); works only inside the class that defines the method. Main is not Poker, so the bare name gives the computer no indication of which class to search, and the statement fails to compile.

A call without the class name looks reasonable, and it is a common source of errors. The statement playGame(); can appear inside the class that contains the definition, such as within main() or another subroutine of that class. Outside that class, however, the bare name is not enough. The rest of this article traces what the compiler does with each form of the call so you can see exactly why one compiles and the other does not.

Where the Compiler Looks for a Method

A static method's full name includes the name of the class where it is defined. The method is public, so other classes are allowed to call it. But the method name alone does not tell the computer which method is meant. The class name tells the computer which class to search, and that is why the qualified form Poker.playGame() is a complete reference to one specific method.

Trace what happens when the compiler meets a bare call playGame(); inside Main. The bare name has no qualifier, so the compiler has only one place to start: the class where the statement appears. Main does not define playGame(), so the search finds nothing to match. Because the call cannot be resolved to any method, the program fails at compile time. The diagram below follows that path.

playGame(); in Mainbare call, no qualifierSearch Main forplayGamethe only class checkedNo matching method inMaindefinition lives in PokerCompile-time failurecall cannot be resolvedcompiler starts herenothing foundreported
When a call has no class name in front of it, where does the compiler look for the method, and why does it fail to find it in the other class?

Because a static method belongs to its class rather than to an object, the class name is the only handle the call needs. You do not create a Poker object before calling playGame(). The call names the class directly, and the class name is what points the compiler to the method.

The ClassName.methodName() Form

A static method is called from another class by writing the class name, a dot, and the method name, followed by the parentheses and a semicolon. The general form is ClassName.methodName(); Each part has a specific job. Read the parts in order, from left to right, to see what the compiler is told at each step.

Pokerclass to search.separates class from methodplayGamemethod name()call parentheses;ends the statement
What does each part of ClassName.methodName() tell the compiler, and in what order does it read them?

Reading left to right, the compiler first sees Poker and knows which class to search. The dot then links that class to the method name that follows. The name playGame identifies the method inside that class, and the parentheses mark it as a call. Together, the qualified reference names exactly one method, which is why the form is needed whenever the calling code is outside the defining class.

Tracing a Correct Call from Main

The following example uses two classes. Poker defines a public static method playGame(). Main is a separate class, and its main() method calls the Poker method by writing the class name in front of the method name.

Code walkthrough
class Poker {
    public static void playGame() {
        System.out.println("Playing poker");
    }
}

class Main {
    public static void main(String[] args) {
        Poker.playGame();
    }
}
  1. 1
    The Poker class holds the definition of playGame(), which is declared public and static.
  2. 2
    The Main class calls playGame() from its main() method.
  3. 3
    The statement Poker.playGame(); names the class first, so the compiler searches Poker and finds the method.
  4. 4
    When the call runs, the body of playGame() executes and prints the text shown in the output.
  • Poker defines the static method playGame().
  • Main is a different class, so the call must name Poker.
  • Poker.playGame(); tells the compiler to search Poker for playGame.
Output
Playing poker

Notice that Main does not need an object of type Poker. Because playGame() is static, the call goes straight to the class. This is the same design that lets Poker.playGame(), Roulette.playGame(), and Blackjack.playGame() each name a different method without creating any objects first.

Correct and Incorrect Calls Side by Side

Inside Main, the only difference between a call that compiles and one that fails is the class name. The before and after versions below use the same method and differ only in that prefix.

Before
class Main {
    public static void main(String[] args) {
        playGame();
    }
}

Bare call fails to compile from Main

After
class Main {
    public static void main(String[] args) {
        Poker.playGame();
    }
}

Qualified call compiles and runs

playGame();fails to compilePoker.playGame();compiles and runs
What is the difference between a call that compiles and one that fails, written side by side?

Several Classes Sharing One Method Name

The class name also solves a naming problem. Many classes can each define a method called playGame(). The qualifier separates them: Poker.playGame(), Roulette.playGame(), and Blackjack.playGame() all share the method name but belong to different classes. Because each full name includes its class, the same method name can be reused in several classes without any confusion about which one is meant.

Mistakes Beginners Make with Bare Calls

  • Common mistake

    Calling a static method from another class using only the method name

    What it looks like
    Inside Main: playGame();
    Why it fails

    A bare call works only inside the class that defines the method. From Main, the name does not tell the computer which class to search.

    Do this instead
    Write the class name, a dot, and the method name: Poker.playGame();
  • Common mistake

    Assuming a call that works inside Poker will also work in Main

    What it looks like

    A playGame(); statement that runs inside Poker's main() is copied unchanged into Main.

    Why it fails

    The statement works inside Poker only because the method is defined there. Moving it to another class removes the context that made the bare name valid.

    Do this instead

    Add the class name when the call is moved to another class.

  • Common mistake

    Forgetting the dot between the class name and the method name

  • Common mistake

    Assuming the class name is optional when the method is static

    Why it fails

    Being static means the method belongs to the class, but the call from another class still needs the class name to point to that method.

Practice Calling Across Classes

EASY

Assume Poker contains a public static method playGame(). Write the statement that should appear inside the main() method of a separate class Main so that it calls playGame() from Poker and compiles.

Hints
  • The call must name the class where the method is defined.
  • Use the form ClassName.methodName();
  • Put a dot between the class name and the method name.
MEDIUM

Explain, in one or two sentences, why the statement playGame(); fails to compile inside Main but Poker.playGame(); does not.

Hints
  • Think about which class the compiler searches in each case.
  • Refer to what the class name tells the computer.

Key Takeaways

  • A static method is called from another class by writing the class name, a dot, and the method name: ClassName.methodName();
  • A bare call such as playGame(); works only inside the class that defines the method, and from another class it fails to compile.
  • The class name tells the computer which class to search, so the qualified form identifies one specific method.
  • Because the class name is part of the full method name, Poker.playGame(), Roulette.playGame(), and Blackjack.playGame() can coexist without conflict.
  • A static method belongs to its class, so calling it from another class needs the class name but no object.