Monday, May 26, 2025

Access modifiers and scope basics

 Classes, methods, and instance variables each have what is called an access modifier.

There are four in Java:

  • public
  • [nothing there, but this means something]
  • protected
  • private

The first one anyone encounters when they are new to Java is public. This is the loosest of the access modifiers, meaning that anyone and anything can see or call it.

Next on the hierarchy is the “default” access modifier (also called “package-private”). You can create packages, which are directories of files that help you organize your Java. Things marked default are visible and accessible to anyone and anything, so long as they live in the same package.

Still further down is “protected.” This, in my experience, is the least common. I’ve made hundreds, if not thousands, of classes, methods, or variables default, public, or private. I can’t recall ever having made something protected. In any case, it’s still important to know what “protected” does.

There’s a kind of relationship between classes that, for now, I’ll just summarize as “every X is a Y”—“Every Dog is an Animal.” This is a key concept that will very soon get its own article.

Something marked as “protected” is only shielded from view by things that are both:

  1. Not in that “is a” relationship
  2. AND in a different package
Finally, we come to “private,” the most restrictive access modifier. What is private is only visible to things that are in the same class.

Related to this is the notion of the scope of variables.

Inside some curly braces, there may only be one variable of a given name; outside of that particular set of curly braces, you may reuse names.

For example:

At some point in some code, we have:

for(int i =0; i < 100; i++){
}

And things happen inside. What is illegal is the following:

for(int i =0; i < 100; i++){
int i = 42;
}

This is illegal since i was already declared in the setup of the loop, and this attempts to either recreate the same variable or create a new one with the same name. If all you want to do is change i’s value, the proper way to do that, once initialized, is simply with i = 42;

However, nothing prevents you, at some later time, from using i to count through another for loop.

 Referring back to
for(int i =0; i < 100; i++){
}

If now here (i.e., after the loop) I try to access i, that would result in an error. The variable i ceases to exist after the curly braces at the end of the loop, so trying to access that i either before or after the loop would result in an error.

This is not limited to indexed-for loops. Any kind of loop, or any if-statement bounded by braces, will have this kind of problem. The area in which a variable can be accessed or changed is its scope. The scope begins when the variable is created and ends at the closing curly brace of the level in which it was created. This is also true for methods.

public static int foo(int x){

Start of x’s scope—inside the whole method

int res = 1;

Start of res’s scope—inside the whole method

for(int i = 1; i< x; i++){

Start of i’s scope—inside just the loop

res *= i;

 

}

End of i’s scope

return res;

 

}

End of res’s, x’s scope


When trying to access a variable, be sure you are trying to do so from the proper scope. Other languages (like JavaScript) are more tolerant of trying to access things from outside their scope in certain situations (and can “lift” things into scope in certain situations), but Java does not do this. If you try to access anything outside of scope, you will get an error. 

No comments:

Post a Comment

Switch

 Other than if/if-else/if-else if-else and the ternary operator, there is yet another common and important conditional expression in Java th...