Java Modifiers
Access Modifiers
Access modifiers determine where a Java class, method, or field can be accessed.
- default. The Java element is accessible to any class in the same package.
- public. The Java element is accessible to any class.
- private. The Java method or field is accessible within the current class.
- protected. The Java method or field is accessible within the current class and subclasses.
Other Modifiers
Other modifiers define how a Java element can be used, or how it interacts with other classes.
- abstract. An abstract class contains some methods that are not defined and must be implemented in subclasses. An abstract method contains no body and must be overridden in subclasses.
- [#Final|final]]. A final class cannot be used as a superclass. A final method cannot be overridden by a subclass. A final field's value cannot be changed.
- static. A static method or field is shared by all instances of the current class.
- synchronized. A synchronized method will seize control of the class while it is running. This is used in a multithreaded environment to make sure two threads do not access an object at the same time.
- transient. A transient field is not saved if the object is serialized.
- volatile. A volatile field's value can be changed by unsynchronized threads.
- native. A native method is invoked from Java but written in another "native" language, usually C or C++.
Default
Default is the name of the access of classes, variables, and methods if you don’t specify an access modifier. A class’s data and methods may be default, as well as the class itself. A class’s default features are accessible to any class in the same package as the class in question. A default method may be overridden by any subclass that is in the same package as the superclass. A default method may be overridden by any subclass that is in the same package as the superclass. Default is not a Java keyword;
Public
A public class, variable or method may be used in any Java program without restriction. Any public method may be overridden by any subclass. Logically the main method have to be public.
Private
Top-level (not inner) classesmay not be declared private. A private variable or method may be used only by an instance of the class that declares the variable or method. Private data can be hidden from the very object that owns the data.
1. class Complex { 2. private double real, imaginary; 3. } 4. 5. 6. class SubComplex extends Complex { 7. SubComplex(double r, double i) { 8. real = r; // Trouble! 9. }
In the constructor for class SubComplex (on line 8), the variable real is accessed. This line causes a compiler error, with a message that is very similar to the message of the previous example:
“Undefined variable: real.”
The private nature of variable real prevents an instance of SubComplex from accessing one of its own variables!
Protected
Only variables and methods may be declared protected. A protected feature is available to all classes of the same package. Different package subclasses has the following limited privileges:
- override protected methods of the superclass.
- instances may read and write protected fields they inherit form the superclass. An instance may not read and write protected instances of other instances.
- instances may call protected methods they inherit form the superclass. An instance call protected instances of other instances.
The protected and default access control levels are almost identical, but has one critical difference. A default member may be accessed only ig the class accessing the member belongs to the same package, whereas a protected mener cab be accessed (though inheritance) by a subclass even if the subclass is in a different package.
Example default access ====================== 1. package sportinggoods; 2. class Ski { 3. void applyWax() { . . . } 4. }
The applyWax() method has default access. Now consider the following subclass:
1. package sportinggoods; 2. class DownhillSki extends Ski { 3. void tuneup() { 4. applyWax(); 5. // other tuneup functionality here 6. } 7. }
The subclass calls the inherited method applyWax()
. This is not a problem as long as both the Ski
and DownhillSki
classes reside in the same package. However, if either class were to be moved to a different package, DownhillSki
would no longer have access to the inherited applyWax()
method, and compilation would fail. The problem would be fixed by making
applyWax()
protected on line 3:
Example protected access ======================== 1. package adifferentpackage; // Class Ski now in // a different package 2. class Ski { 3. protected void applyWax() { . . . } 4. }
Subclasses and Method Privacy
Java specifies that methods may not be overridden to be more private. So the legal override methods is:
private --> default --> protected --> public
The rules of overriding are:
- private method may be overridden by a private, default, protected, or public method.
- default method may be overridden by a protected or public method.
- protected method may be overridden by a public method.
More Modifiers
Final
The final modifier applies to classes, variables, and methods.
- A final
class
cannot be subclassed. - A final method can not be overridden.
- A final
variable
cannot be modified once it has been assigned a value. (Const in C++).
If a final variable is a reference to an object, it is the reference that must stay the same, not the object. Also not final variables of the object can be changed.
Abstract
The abstract modifier can be applied to classes and methods.
- An abstract class may not be instantiated
- An abstract method has the signature of the superclass and has to implemented in the subclass.
- An abstract class has one or more abstract methods. Not all methods need to be abstract.
Static
The static modifier can be applied to variables, methods, and even a strange kind of code that is not part of a method. Static belongs to a class rather than being associated instances of a class. A static variable occurs only once no matter how much instances of the class exist.
1. class Ecstatic{ 2. static int x = 0; 3. Ecstatic() { 4. x++; 5. } 6. }
Variable x is static; this means that there is only one x, no matter how many instances of class Ecstatic might exist at any moment. There might be one Ecstatic instance, or many, or even none, yet there is always precisely one x. The 4 bytes of memory occupied by x are allocated when class Ecstatic is loaded. The initialization to 0 (line 2) also happens at class-load time. The static variable is incremented every time the constructor is called, so it is possible to know how many instances have been created. Reference to static variables can be made on 2 ways:
- Via a reference to an instance of the class.
- Via the class name (Ecstatic.x, Math.PI and Math.E)
Static methods
- A static method may access only the static data of its class; it may not access nonstatic data.
- A static method may call only the static methods of its class; it may not call nonstatic methods.
- A static method has no
this
. - A static method may not be overridden to be nonstatic.
Static Initializers It is legal for a class to contain static code that does not exist within a method body. A class may have a block of initializer code that is simply surrounded by curly braces and labeled static. For example:
1. public class StaticExample { 2. static double d = 1.23; 3. 4. static { 5. System.out.println("Static code: d=" + d++); 6. } 7. 8. public static void main(String args[]) { 9. System.out.println("main: d = " + d++); 10. } 11. }
Line 4 is known as static initializer code. The code inside the curlies is executed exactly once, at the time the class is loaded. At class-load time, all static initialization (such as line 2) and all free-floating static code (such as lines 4–6) are executed in order of appearance within the class definition. The output from this code is:
Static code: d=1.23 main: d = 2.23
Static imports Any nonprivate feature may be statically imported into a source file of the same package; only a public feature may be statically imported into a source file in a different package.
Feature Access Mode | Feature Static Import Same Package |
Feature Static Import Different Package |
---|---|---|
public | Yes | Yes |
protected | Yes | No |
default | Yes | No |
private | No | No |
Native
The native modifier can refer only to methods. Like the abstract modifier, native indicates that the body of a method is to be found elsewhere. In the case of abstract methods, the body is in a subclass; with native methods, the body lies entirely outside the Java Virtual Machine(JVM), in a library. Native code is written in a non-Java language, typically C or C++, and compiled for a single target machine type.
1. class NativeExample { 2. native void doSomethingLocal(int i); 3. 4. static { 5. System.loadLibrary("MyNativeLib"); 6. } 7. }
Callers of native methods do not have to know that the method is native. The call is made in exactly the same way as if it were nonnative.
Transient
The transient modifier applies only to variables. A transient variable is not stored as part of its object’s persistent state.
Volatile
The volatile modifier is not in common use. Only variables may be volatile; declaring them so indicates that such variables might be modified asynchronously, so the compiler takes special precautions. Volatile variables are of interest in multiprocessor environments.
Synchronized
The synchronized modifier is used to control access to critical code in multithreaded programs.
Visibility
Visibility | Public | Protected | Default | Private |
---|---|---|---|---|
From the same class | Yes | Yes | Yes | Yes |
From any class in the same package | Yes | Yes | Yes | No |
From a subclass in the same package | Yes | Yes | Yes | No |
From a subclass ouside the same package | Yes | Yes, (Inheritance) | No | No |
From any non-subclass outside the package | Yes | No | No | No |
See also