Apparent Hierarchies of Packages
In this post http://java.sun.com/docs/books/tutorial/java/package/usepkgs.html
into the paragraph "Apparent Hierarchies of Packages" is written:
"" At first, packages appear to be hierarchical, but they are not. For example, the Java API includes a java.awt package, a java.awt.color package, a java.awt.font package, and many others that begin with java.awt. However, the java.awt.color package, the java.awt.font package, and other java.awt.xxxx packages are not included in the java.awt package. ""
but if I unjar rt.jar I discover that java.awt.color and java.awt.fo开发者_运维问答nt are mapped in a hierarchical way: java/awt/color and java/awt/font so do I understand bad or in that post is there an error?
However is it possible to create not hierarchical packages? logical packages names that don't match a phisical packages structure?
The article you reference explains the point in the next paragraph. The names of the packages are used to indicate relationships to programmers' eyes but do not have any relationship in the eye of the compiler. As the article explains importing java.awt.*
will not import any classes in java.awt.font
they are completely separate packages that do not have any hierarchical relationship in the programming language. To import all the classes in java.awt.font
you have to import java.awt.font.*
and that does not import any classes in the parent package java.awt
or in sibling packages like java.awt.color
.
So even though there is an apparent hierarchical relationship to the programmer there really isn't any in the language. To access classes in a given package you have to import them from their exact package.
If packages were actually hierarchies then one might imagine that this would be the case. However the hierarchy is only there to organise the code and give hint to programmers that a given set of packages are intended to be used together.
The article continues
Importing java.awt.* imports all of the types in the java.awt package, but it does not import java.awt.color, java.awt.font, or any other java.awt.xxxx packages.
So it just describes the general behaviour of the import statement: import package.*
imports all classes from package
but no classes from sub packages.
Yes, the class files are in rt.jar just where we expect them, this is only about importing classes in java source files.
Edit
Yes, the tutorial it adds a certain degree of confusion.
Try to understand a package as a collection of classes that share a common namespace. java.awt
is a namespace, java.lang
and java.awt.color
is another one. And now understand, that the java.awt
and the java.awt.color
namespaces are not related. java.awt.color
is not a 'child' namespace of java.awt
. And indeed, there is no rule in Java that you have to put certain classes in certain 'child' packages. If there was a hierarchie, I'd expect some rules like implementations have to be declared in a 'child namespace' of the interface, or so. But there aren't any
Yes, the actual mapping for namespaces to filesystems introduces a folder hierachie, where color is a folder inside awt. That's pretty practical, otherwise we'd need a mapping between package namespace and physical location of the classes in the filesystem. Now we can determine the location from the package namespace. And that leads to the impression, that this hierarchie is true for the package namespaces as well.
But this is not the case. And that's what the tutorial wants to say.
(thanks for the question, I learned and understood a lot while thinking of the answer ;) )
What the tutorial means is that there is no concept of sub-packages in Java. A package may physically lie in a sub-folder in the file system, but that does not mean that it will be automatically included (see Andreas' answer).
It also does not give the classes in the higher-level package rights to access package-private (default-scoped) classes, as you might expect if there was a package hierarchy.
The naming scheme is hierarchical, as well as the content of jar files.
However, there is no connection between java.awt and java.awt.color, that is, for example, if you declare a class as package private (with no modifiers) in package foo, it will be accessible from foo, but not from foo.bar.
Think of the hierarchy like a file system. In Java, packages are like directories and classes are like files. Packages are meant to contain a set of related classes. When there are groups of packages that are logically related, they can be named so they appear as a member of a larger hierarchy. Looking at the above java.awt.* example, I could put the classes for AWT in jar1. It would have the following structure:
jar-1
\-java
\-awt
In the awt directory you'll find the classes and interfaces which declare themselves to be members of package java.awt.
Now I want to implement some fonts for awt but I put them in a separate jar:
jar-2
\-java
\-awt
\-fonts
The font directory is where the classes and interfaces are for the fonts I created for awt.
When you go to program using AWT and my fonts, first you have to include both jar-1 and jar-2 in your CLASSPATH. When you go to include the classes, you don't get any feedback as to which jar the compiler found them in.
//this loads all classes in the java.awt directory
// which happen to come from jar-1
include java.awt.*
If you want the fonts,
//Load all classes in the java.awt.fonts directory
// which happen to come from jar-2
include java.awt.fonts.*
To the compiler and the runtime the hierarchy looks like one big tree. That does not mean that the classes all physically reside in the same place. Having said that I must make two points; 1) Separating packages in the same hierarchy into different jars is not recommended as it will be confusing and a maintenance headache, and 2) declaring packages as extensions of someone else's package structure is extremely bad form, even if the compiler lets you do it.
精彩评论