访问控制很烦人,You're going to love this artical.
Access modifiers(from less restrictive to more restrictive):
public、protected、default(package access)、private
Non-access modifiers(inluding final, abstract and strictfp)
1. class Accesses
(1) Default acess
A class with default access has no modifier preceding it in the declaration!
Think of default access as package-level access, because a class with default access can be seen only by classes within the same package.
(2) Public access
A class declaration with the public keyword gives all classes from all packages access to the public class.
Remenber that a class can use just two of the four access control levels :default or public !
(3) Other (Nonaccess) Class Modifiers
You can modify a class declaration using the keyword final,abstract.
(3-1)Final classes
When used in a class declaration, the final keyword means the class can't be subclassed. In other words, no other class can ever extend (inherit from) a final class. The methods whose class arefinal are default final.
(3-2)Abstract Classes
An abstract class can never be instantiated.
The methods marked abstract end in a semicolon rather than curly braces.
You can, however, put nonabstract methods in an abstract class.
It is legal that an abstract class has no abstract methods.
2. Declare Class Members
(0)Access Modifiers
Whereas a class can use just two of the four access control levels (default or public), members can use all four:
public、protected、default、private
The default and protected access control types have almost identical behavior, except for one difference that will be mentioned later.
(1)Public Members
When a method or variable member is declared public, it means all other classes, regardless of the package they belong to, can access the member (assuming the class itself is visible).
(2)Private Members
Members marked private can't be accessed by code in any class other than the class in which the private member was declared. A private member isinvisible to any code outside the member's own class.
What about a subclass that tries to inherit a private member of its superclass?
When a member is declared private, a subclass can't inherit it.
A subclass can't see, use, or even think about the private members of its superclass. You can, however, declare a matching method in the subclass. But regardless of how it looks,it is not an overriding method!
(3)Protected and Default Members
The protected and default access control levels are almost identical, but with one critical difference. A default member may be accessed only if the class accessing the member belongs to the same package, whereas a protected member can be accessed (through inheritance) by a subclass even if the subclass is in a different package.
Take a look at the following two classes:
package certification;
public class OtherClass {
void testIt() { //No modifer means method has default access
System.out.println("OtherClass");
}
}
In another source code file you have the following:
package somethingElse;
import certification.OtherClass;
class AccessClass {
public static void main(String[] args) {
OtherClass o = new OtherClass();
o.testIt();
}
}

From the preceding results, you can see that AccessClass can't use the OtherClass method testIt() because testIt() has default access, and AccessClass is not in the same package as OtherClass. So AccessClass can't see it, the compiler complains.
Default and protected behavior differ only when we talk about subclasses. If the protected keyword is used to define a member, any subclass of the class declaring the member can access it through inheritance. It doesn't matter if the superclass and subclass are in different packages, the protected superclass member is still visible to the subclass (although visible only in a very specific way as we'll see a little later).
NOW, let's see Protected Details.
3. Protected Details
What does it mean for a subclass-outside-the-package to have access to a superclass (parent) member? It means the subclass inherits the member. It does not, however, mean the subclass-outside-the-package can access the member using a reference to an instance of the superclass. In other words, protected = inheritance.
Protected does not mean that the subclass can treat the protected superclass member as though it were public. So if the subclass-outside-the-package gets a reference to the superclass (by, for example, creating an instance of the superclass somewhere in the subclass' code), the subclass cannot use the dot operator on the superclass reference to access the protected member.
To a subclass-outside-the-package, a protected member might as well be default (or even private), when the subclass is using a reference to the superclass. The subclass can see the protected member only through inheritance.
package certification;
public class Parent {
protected int x = 9; // protected access
}
package other;
import certification.Parent;
class Child extends Parent {
public void testIt() {
System.out.println("x is " + x); // No problem, Child inherites x
Parent p = new Parent(); // Can we acess x using the p reference ?
System.out.println("x in parent is " + p.x); // compiler error!
}
}
The compiler is more than happy to show us the problem:
For a subclass outside the package, the protected member can be accessed only through inheritance.
Can access modifiers be applied to local variables? NO!
There is never a case where an access modifier can be applied to a local variable.
4. Nonaccess Member Modifiers:final
(1) Final Methods
The final keyword prevents a method from being overridden in a subclass.
The special method constructor can not be final !
(2)Final Fields or local Variables
A final variable has kind of types:
1)It can be a compile-time constant that won't ever change.
2)It can be a value initialized at run time that you don't want changed.
也算就是说final变量要么在声明时赋值(此时为编译时常量),要么在使用之前赋值(此时为运行时常量,编译器保证这一点)。因此final并不意味着变量的值一定实在运行时已知的。
如果是运行时常量,它们初始化的地方有限制:
instance final field 使用之前只能在构造函数或instance block中初始化,不能在实例方法中初始化。
static final filed 只用之前只能在static block初始化。
public class Final {
final int x = 2; // compile-time constant
final int y; // blank final, It must be initialized before used, and
// the compiler ensures this
final int z;
static final int a;
static {
a = 8;
System.out.println("a is initialized to " + a);
}
{
z = 4;
System.out.println("z is initialized to " + z);
}
Final() {
y = 6;
System.out.println("y is initialized to " + y);
}
public void testFinal() {
final int h; //It must be initialized before used, and
// the compiler ensures this
h = 6;
System.out.println("h is initialized to " + h);
}
public static void main(String[] args) {
new Final().testFinal();
}
}
(3) Final Arguments
Method arguments are essentially the same as local variables.
Method argument is declared as final, which of course means it can't be modified within the method.
5. Nonaccess Member Modifiers:static
Things you can mark as static:
Methods
Variables(Non-local)
A class nested within another class, but not within a method.
Initialization blocks
Things you can't mark as static:
Constructors (makes no sense; a constructor is used only to create instances)
Classes (unless they are nested)
Interfaces
Method local inner classes
Inner class methods and instance variables
Local variables
You must never, ever, ever mark a class as both final and abstract. They have nearly opposite meanings.