Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The use of visibility modifiers in Java

Tags:

java

modifier

class Orange{

    Orange(){
    }

}

What is the difference between the usage of the modifier - in this case, package-private - in front of the class and in front of the constructor? I think the modifier in front of the constructor means it is allowed to instantiate an instance of the class Orange. But what about the modifier in front of the class?

like image 285
joy Avatar asked May 24 '13 03:05

joy


2 Answers

To start with there are 4 access levels created by 3 access modifiers.

  1. public - accessible everywhere
  2. protected - accessible in the same package and in the children
  3. default - accessible only in the same package
  4. private - accessible only in the same class.

You are correct about - Modifiers at the level of constructors are directly related to the instantiation of the class.

Modifiers at the level of Class decide the accessibility of the Class.

like image 59
Rishikesh Dhokare Avatar answered Oct 04 '22 19:10

Rishikesh Dhokare


First, to assuage any fears, the code you've provided is perfectly valid Java syntax.

In effect, you've created a class that can only be instantiated/used by other classes in the default package. It would also work if you defined it in a package (e.g. package foo;) since only the classes in package foo could see this class).

Now, to the crux of the question.

There are different ways to control access to fields and members. and they each do different things.

  • private visibility is the least visible. Only the defining class can access the field.

  • No modifier, or package private is the second least visible. The defining class and all classes within the package may access the field, but subclasses and the rest of the world cannot.

  • protected is the second most visible. Only other classes are prohibited from accessing the field.

  • public is the most visible. Everything can access the field.

Modifiers at the level of the class get interesting. This comes from the Java Language Specification, §8.1.1:

The access modifier public (§6.6) pertains only to top level classes (§7.6) and to member classes (§8.5), not to local classes (§14.3) or anonymous classes (§15.9.5).

The access modifiers protected and private (§6.6) pertain only to member classes within a directly enclosing class or enum declaration (§8.5).

The modifier static pertains only to member classes (§8.5.1), not to top level or local or anonymous classes.

It is a compile-time error if the same modifier appears more than once in a class declaration.

If two or more (distinct) class modifiers appear in a class declaration, then it is customary, though not required, that they appear in the order consistent with that shown above in the production for ClassModifier.

In general, a class declaration appears something like this:

ClassDeclaration:
    NormalClassDeclaration
    EnumDeclaration

NormalClassDeclaration:
    ClassModifiers(opt) class Identifier TypeParameters(opt)
                        Super(opt) Interfaces(opt) ClassBody

Anything with (opt) is considered optional.

So, what does this pare down to?

  • The JLS mandates that a class does not need a [class] modifier.
  • The JLS mandates that, if a [class] modifier is present, then it follows one of these rules:
    • If the modifier is public, then it is only applicable to top level classes and member classes.
    • If the modifier is protected or private, then it is only applicable to member classes within a directly enclosing class or enumeration.
    • The static modifier may appear, but is only applicable to member classes.

Constructors have a similar rule set.

ConstructorDeclaration:
    ConstructorModifiers(opt) ConstructorDeclarator
                                Throws(opt) ConstructorBody

ConstructorDeclarator:
    TypeParameters(opt) SimpleTypeName ( FormalParameterList(opt) )

Again, this breaks down to:

  • The JLS mandates that a constructor does not need a [constructor] modifier.
  • The JLS mandates that a constructor modifier cannot contain abstract, static, final, native, strictfp, or synchronized.
  • The JLS mandates, if no access modifier is specified for the constructor of a normal class, the constructor has default access (§8.8.3, emphasis mine).
like image 44
Makoto Avatar answered Oct 04 '22 21:10

Makoto