Java Scope – Is Package Level Scope Useful?

javascope

I understand the idea of package scope, and at times have even thought I wanted it. However, every time I set down with a serious intent to try using it I discovered it did not fit the needs I thought it would serve.

My main issue always seems to be that the things that I wish to limit the scope of are never in the same package. They may conceptually all be linked, but the logical division of data within the application has them as separate child packages of a larger package.

For instance I may have a Mission model and I want only other Mission tools, like my missionServices, to use some methods. However, I end up with Missions.models and Missions.services as my packages, so the MissionModel and MissionService are not the same package scope. It never seems like there is a situation where packages appropriately contain the things that I would want to have elevated permissions without also included numerous things I do not wish to have those permissions; and rarely do I feel the advantage of package scoping a method justifies modifying my project architecture to place everything in the same package. Often either Aspects or some sort of inversion of control turn out to be the better approach to whatever problem I briefly considered package scoping for.

I'm curious rather this is generally considered true across all Java developers, or is just a fluke of the work I do. Is package scope utilized much in the real world? Are there many cases where it's considered good form to use, or is it seen mostly as a legacy behavior to rarely be exploited in modern development?

I am not asking anything about why package private scope is default, I'm asking when it should be used regardless of the defaults. Most discussions as to why it is default don't really get into when package scope is actually useful, instead arguing simply for why the other two commonly used scopes should not be default so package wins by process of elimination. In addition, my question is about current state of development. Specifically, have we developed to the point where other tools and paradigms make package scope less useful then it was back when the decision to make it default made sense.

Best Answer

Throughout the java.util.* package there are instances where code is written with package level protection. For example, this bit of java.util.String - a constructor in Java 6:

// Package private constructor which shares value array for speed.
String(int offset, int count, char value[]) {
    this.value = value;
    this.offset = offset;
    this.count = count;
}

or this getChars method:

/** Copy characters from this string into dst starting at dstBegin. 
    This method doesn't perform any range checking. */
void getChars(char dst[], int dstBegin) {
    System.arraycopy(value, offset, dst, dstBegin, count);
}

The reason for this is that the designers of the code (and java.util.* can be thought of as a rather large library) wanted the ability to have faster performance at the cost of a loss of various safety (range checks on arrays, direct access to other fields that imply the implementation rather than the interface, 'unsafe' access to parts of the class that are otherwise considered to be immutable via public methods).

By restricting these methods and fields to only be accessed by other classes in the java.util package, it makes for closer coupling between them but also avoids exposing these implementation details to the world.

If you are working on an application and don't have need to worry about other users, package level protection isn't something you need to worry about. Other than various aspects of design purity, you could make everything public and be ok with that.

However, if you are working on a library that is to be used by others (or want to avoid entangling your classes too much for later refactoring), you should use the strictest level of protection afforded to you for your needs. Often this means private. Sometimes, however, you need to expose a little bit of the implementation details to other classes in the same package to avoid repeating yourself or to make the actual implementation a bit easier at the expense of the coupling of the two classes and their implementations. Thus, the package level protection.

Related Topic