Java's `private` Isn't What You Think

I was playing around with Java interfaces recently and looking at the Comparable<T> interface. To officially use it, you have to implement a method called compareTo inside your class. I built a simple Employee class to test it out, and this is the code I came up with:

public class Employee implements  Comparable<Employee> {
    private double salary;

    public static void main(String[] args) {
        var e = new Employee();
        System.out.println(e.getId());
    }

   private double getSalary() {
        return this.salary;
   }

   @Override
   public int compareTo(Employee other) {
       System.out.println(other.getSalary());
        return Double.compare(this.salary, other.salary);
   }
}

The Surprise in the Code

Look closely at the compareTo method at the bottom. I am directly calling other.getSalary() and accessing other.salary.

If you are like most developer who are learning Java, your first instinct is probably to think: “Wait a minute. salary and getSalary() are both marked as private. This should cause a compiler error!

I thought the exact same thing. But surprisingly, this code compiles and runs perfectly fine.

Class Privacy vs. Object Privacy

The confusion happens because of a common misunderstanding about how private actually works in Java. When we first learn programming, we are taught that private means “hidden from the outside world.” Because of that, we assume it means object-level privacy—the idea that one object cannot see another object’s private data.

But Java doesn’t care about individual objects here. It cares about the class.

The Golden Rule: Java checks where the code is written, not which object is running it.

Because the compareTo method is physically written inside the Employee class, it has full permission to look at the private data of any Employee object in the program. It doesn’t matter if it belongs to this current object or the other object passed in as a parameter.

Why This is Super Useful

This tiny detail is actually a lifesaver for developers. It allows us to easily compare two objects of the same type without a struggle.

If Java didn’t work this way, we would be forced to create public getter methods for every single private variable just to compare them. That would completely ruin the point of hiding our data from the rest of the program.

So, the next time you use the private keyword, remember: you are hiding your data from other classes, not from other objects of the same type.