Access

index
BASIC

Access refers to where in a program the name of a class, interface, variable, or method may be used.

Static and instance (non-static) variables and methods can be declared within a class. These variables and methods can be used anywhere in the same class simply by mentioning their names, except that instance variables cannot be used by static methods or in static variable initializations.

class QuickExample1 {
    int doubleN() { return add(n, n); } // uses n and add(int) (both declared below)
    int add(int x) { return x + n; } // uses n
    int n = 3;
    static int halfN() { return n / 2; } // illegal--n is not static
    static int nPlusOne = n + 1; // illegal--n is not static
}

Usually, variables should be declared near the top of the class, before any methods. In this example n was declared later, just to show that it is legal to do so. Methods may be declared in any order.

Variables declared within a block (the body of a method is always a block) are available from the point of declaration to the first closing brace. (The braces enclosing the contents of a class or interface do not form a block.)

{
    x = 1; // not legal here
    int x;
    x = 2; // legal here
}
x = 3; // not legal here

The above deals with the usual case of using variables and methods in the same class that declares them. Often, we want to use methods (and less often, variables) in one class that are declared in some other class.

To reference a static method or variable in some other class, precede the name of the variable with the name of the class, followed by a dot. For example,

root10 = Math.sqrt(10.0);

To reference a non-static method or variable in some other class, precede the name of the variable with the name of the object, followed by a dot. For example,

myFather.askForMoney();

INTERMEDIATE

There are four levels of access: private, package (default: no keyword), protected, and public. These levels apply to classes, interfaces, methods, and variables declared within a class or interface (but not variables declared within a method).

Note: There is a keyword package, but Java uses it for something else entirely, namely, to specify which folder/directory contains the class.
private
Available only within the class where it is defined.
package
Available throughout the "package" (folder or directory) in which it is defined.
protected
Available throughout the package, and to any subclasses, wherever they may be.
public
Available anywhere.

Classes and interfaces are usually given public or package access.

Variables declared within an interface are automatically public.

Variables declared within a class (both instance variables and static variables) should normally be private; unfortunately, this is not the default. The programmer should explicitly mark each variable as private unless and until there is good reason to do otherwise.

Why should most variables be private?

Objects should be maintained in a valid state at all times, except when they are being manipulated by a method within the defining class. It is the responsibility of the class to ensure the validity of its objects.

For example, consider a class Person with an instance variable age. Presumably, age should never be negative. If an error occurs that causes age to become negative, and the variable is private, then we know the error must have occurred within the class Person. But if age is not public, the error could be anywhere (in, say, a Lotion that is guaranteed to make a person ten years younger).

STYLE

Normally, a class should declare things in this order:

static variables
instance variables
static methods
instance methods

Variables should be declared private, unless changing the value of the variable cannot affect the validity of the object. To access private variables from outside the class, you can write special methods called getters and setters. For example, if you have a private variable named age, you could write the following methods:

public int getAge() {
    return age;
}
 
public void setAge(int newAge) throws IllegalArgumentException {
    if (newAge < 0) {
        throw new IllegalArgumentException("Age cannot be " + age);
    }
    else {
        age = newAge;
    }
}

The use of getters and setters not only protects your object from errors and malicious behavior in other classes, but it also gives you a lot more flexibility (for example, your object could lie about its age).

It is better to manipulate variables in another class indirectly, through getters and setters, than it is to manipulately them directly. However, there is a still better way.

Object-oriented programming is all about objects talking to other objects, not about objects reaching into other objects and manipulating their variables. So if johnBrown is a Person with an age, you could manipulate that age like this:

johnBrown.setAge(johnBrown.getAge() + 1);

However, it's much better style to have a method in the Person class itself to do this, for example,

public void celebrateBirthday() {
    age = age + 1;
    System.out.println("Happy birthday to me!");
}
and call

johnBrown.celebrateBirthday();