Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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).

You can only declare a public or default class (in case of top level classes only) in Java and these modifiers decide the accessiblity of the class.

I also suggest you to see "Why can't a class or an interface receive private or protected access modifiers?"

Now as for as constructor concerns, a constructor will have aaccess-control of type default when no access-modifier is defined explicitly. So this constructor will have a Package Level Access. Only those class which are defined within that package as that of the class with this default constructor will be able to access it. See "Aren't Java constructors public by default?"

If the constructor is made private, then only the code within that class can access this. For a better understanding of modifiers, you need to see "Access Modifiers In Java"

Modifier of class defines who can access the class. For example public class can be accessed by classes from any package, if no modifier is written the class can be accessed by classes from the same package only.

Modifier of constructor, method and field has the same meaning. However private and protected have more sense. Private can be accessed from the current class only. Protected from its subclasses as far as from just classes from the same package.

Concerning to your question about constructor. Class can have several constructors. Some of them can be private, some other public. You are right that there is no sense to make constructor public if class is package protected: no-one outside package can call this class anyway.

This is exactly like writing public constructors for abstract classes. Since abstract class cannot be instantiated itself its constructors should be protected or private although compiler does not care about this.

BTW using default package is not commonly used and not recommended technique.

The use and types of class level modifiers:

http://javapapers.com/core-java/access-modifiers-in-java-explain/

The use and types of constructor level modifiers:

http://www.careercup.com/question?id=296844#commentThread302715

Class modifiers work similarly to method modifiers. Public, private, final, abstract, etc. work.

Public allows the class and its methods to be accessed by classes from any package.

No modifier only allows classes to be access from it's defined package.

Private would prevent all access (no point to this if using with a top-level class).

Abstract classes allow you to create child classes derived from the parent (abstract) class. For example, you can make an Abstract Shape class and have a Rectangle class extend shape, inheriting all its methods, variables, and forcing it to define any abstract methods.

Access Modifiers:

  • Public - {Can access anywhere in the project}
  • Private - {Can access only inside the class}
  • Protected - {Can access within the package and sub classes}
  • Default - {can access within the package}

Non-Access Modifiers:

  • Static - {for creating class variable and method}
  • Final - {for creating finalized variable and method}
  • Abstract - {for creating abstract method and class}
  • Synchronized - {for threads}

Some brief discussion on the above modifiers in this link. Refer it for the better understanding.

I find the best visibility level in Java to be the default visibility i.e. package visibility, because it enables unit test classes to access all the methods, if the test is placed in the same package as the main class.

Also package visibility is shorter to write since you can omit the visibility declaration, so there is less boiler plate.

The second best visibility level is protected, since in some cases you can create your test classes as sub-classes of your main class. However, as stated before, package visibility works better in most cases, if you use packages properly.

Third, typically if you run Sonar and do code review and static analysis on large projects, I have found out that typically 80% of the methods are public, and 20% are private/protected. Thus, the main idea of using private or protected methods is to protect the data/properties from being accessed by bypassing the accessors. Most of the methods will be typically public anyways.

The most useless visibility level (but unfortunately commonly used) is private as it's impossible to test (without using Reflection and modifying the visibility to something else). Also, private prohibits code re-use in sub-classes, which is the main idea of using object oriented paradigm in the first place, and thus should be avoided. For the same reasons keyword final should be avoided in most cases.

Thus, I find your example to be the best practice how to define the visibility levels, except that your constructor is not public :). However, you are missing the package declaration and unit tests.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top