2. Introduction
• While declaring a field/member in a class or declaring a local variable
(including for advanced Java like multi-threaded programs, JEE etc.),
it’s easy to get confused about what its access/visibility modifier or
other declarations would be. In this presentation, I have summarized
the “How To” identify access/visibility modifiers and other
declarations in Java for fields/members in a class or local variables
(i.e. variables inside a method implementation). I hope this
information would help programmers and developers to create
scalable and loosely coupled Java programs.
• Any suggestions/questions/comments are welcome via the comments
section below.
3. Identify correct access/visibility modifiers and other
declarations for class members and local variables
“static”
• Is the class member dependent on any instance of the object? If “no”, the member
can be declared “static”.
• An inner class can be declared “static” if the class does not depend on any instances
of the outer class.
• Use “static” members to save memory as “static” members are allocated for the
whole class i.e. it’s a class field/variable and thus there is only one per class.
• A declaration of “static” for a local variable is not allowed/applicable.
• Anonymous objects can access “static” fields/members of the class.
• “static” fields of a class are like global fields/variables of the class and thus the same
value is accessible to all instances of the class. This means that it’s important that
supposed to be private/hidden values/functionality are not exposed via any public
“static” method.
• Testing for the functionality that is using a “static” member/field could be
challenging. Please keep this in mind while designing your application/software.
4. Identify correct access/visibility modifiers and other
declarations for class members and local variables
“private”
• Use “private” to encapsulate the field/member. This provides decoupling of the
object from external modifications. So use “private” as much as possible for
fields/states/properties of the object.
• Declaration as “private” helps in encapsulation. Using “private” members help in
changing of the internals of the class possible without breaking/affecting the code
that is using the class.
• “private” members can only be accessed within the class i.e. within the class
methods or the inner/nested classes.
• Use “private” for private methods i.e. the methods meant to be accessed only within
the class and also the methods created for the purpose of modularizing and non-
duplication of the code within the class.
• Use “private” to encapsulate/hide inner classes from being accessed outside the
outer class.
• A declaration of “private” is not applicable/allowed for local variables.
• Anonymous objects can access “private” fields/members of the class.
5. Identify correct access/visibility modifiers and other
declarations for class members and local variables
“public”
• The members declared “public” including fields, methods and inner classes
can be accessed from other classes/packages.
• “public” declaration is used for providing public APIs and libraries.
• “public” members help to provide re-usability.
• A declaration of “public” is not applicable for local variables.
• Anonymous objects can access “public” fields/members of the class.
6. Identify correct access/visibility modifiers and other
declarations for class members and local variables
“final”
• The value of the field or the local variable declared “final” does not change i.e. it is a
constant. In case of reference variable, the internal state of the object the variable is referring
to can be modified or changed but the reference/reference value cannot be modified or
changed.
• The method parameters can also be qualified with the “final” keyword.
• The “final” class field needs to be initialized at the time of declaration or within the
constructor. If initialized within a constructor, it needs to be initialized in all the constructors
in the class.
• Anonymous objects can access “final” local variables from the local outer scope (Please note
that anonymous objects cannot access non-final variables from the local outer scope).
• Use of “final” declaration helps in prevention of accidently modifying the value of the field or
the variable. Also, it provides information to the compiler that can lead to better optimization
of the class file.
• Use of “final” promotes optimizations and prevents logic errors.
• A “final” method cannot be overridden.
• The classes including inner classes declared “final” cannot have sub-classes.
7. Identify correct access/visibility modifiers and other
declarations for class members and local variables
“protected”
• Class fields or members including inner classes declared “protected” can be accessed
by all other classes/objects within the package and by the inherited classes/objects
in another package.
• “protected” is not applicable for local variables.
• If you design your class to be inheritable, carefully choose the member methods that
can be overridden and the fields that can be accessed from subclasses of the class
and declare them “protected”. Be aware that as soon as it is accepted that a class can
have subclasses and “protected” methods and fields, these “protected” methods and
fields are part of the public API of the class and may not be changed later without
breaking subclasses.
Package(default)
• Class fields or members including inner classes declared default (i.e. no
access/visibility modifier) can be accessed by all other classes/objects within the
package.
8. Identify other declarations for class members
and local variables
“volatile”
• Reading and writing variables declared “volatile” are atomic operations. This means that the
operation is completed all at once. Atomic actions/operations cannot be interleaved, so they
can be used without the fear of thread interference.
• Each thread has a CPU cache of its own. When there is more than one CPU, this could be a
problem in multi-threaded programs as the value would not be updated in the main memory
and the other thread reading it would get a stale value. Declaring a variable as “volatile”
would prevent caching of the variable locally in the thread and thus avoid this problem. All
reads and writes in this case will go straight to the main memory.
• One of the common uses of “volatile” is with variables of type long and double as reading
and writing long and double variables are not atomic operations. Note that reading and
writing other primitive type variables and reference variables are atomic operations.
• “volatile” declaration in Java is only applicable to variables. Declaring “volatile” a class or a
method is illegal.
• Using simple atomic variable access is more efficient than accessing these variables through
synchronized code, but this requires more care by programmers to avoid memory
inconsistency errors (error that causes different threads to have inconsistent views/values for
the same data).
9. Identify other declarations for class members
and local variables
“transient”
• Members/fields declared as “transient” will not be serialized when it is
persisted (to streams of bytes).
• For example, if the field is a derived field, you can save storage while
persisting the object by declaring it as “transient”.
• When an object is transferred through the network, the object needs to be
serialized. Serialization converts the object state (its properties) to serial
bytes. These bytes are transferred to the other side and the object is
recreated from these bytes. Member variables/fields that are declared
“transient” are not transferred (they are lost intentionally).
10. Identify other declarations for class members
and local variables
“synchronized”
• “synchronized” declaration locks the associated object while invoking a method or a code
block declared “synchronized” so that only one thread can invoke the method or the code
block on the object and thus prevents race condition (this happens when more than one
thread simultaneously enters a certain part of the program, also known as critical region, in a
way that causes conflict).
• Attempting to declare “synchronized” with an associated null object will throw
NullPointerException.
• Not applicable for class fields or local variables.
“abstract”
• “abstract” declaration on methods is used to defer the implementation of the method to its
subclass. In this case, the class containing the method needs to be declared “abstract” as
well.
• “abstract” declaration on classes is used when the particular class has one or more “abstract”
methods.
• Not applicable for class fields or local variables.
11. Identify correct declaration for class members and local
variables for use within Anonymous Objects and
Lambda Expressions
Anonymous Objects/Lambda Expressions
• From anonymous objects and lambda expressions, both read and write access
to instance fields and static fields are possible.
• Local variables in the local outer scope has read access only from anonymous
objects and lambda expressions. And, to access from within an anonymous
object or a lambda expression, the local variable in the local outer scope must
be “final”. It need not be declared “final” but it must be implicitly final for the
code to compile.
• Default methods cannot be accessed from within lambda expressions.
12. Conclusion
• This presentation is meant to be a reference/guide to aid in the
software/applications development using Java as the programming
language.
• References I used to create this presentation are wiki pages/internet,
algorithm/programming related courses and my past work
experience.
Thank you!