Are packages (that share a name) combined during compliation?

53 Views Asked by At

I'm almost certain this question has been asked, but I'm not sure what to search for regarding it.

Anyway, I was was curious if it would be possible to create a class that extends ByteBuffer. I thought it would be impossible due to ByteBuffer having package-private constructors:

// package-private
ByteBuffer(int mark, int pos, int lim, int cap, byte[] hb, int offset) {
    super(mark, pos, lim, cap);
    this.hb = hb;
    this.offset = offset;
}

// Creates a new buffer with the given mark, position, limit, and capacity
//
ByteBuffer(int mark, int pos, int lim, int cap) { // package-private
    this(mark, pos, lim, cap, null, 0);
}

However, I found out if you create your class in a package that shares a name with its parent, then it compiles perfectly.

package java.nio;

public class Test extends ByteBuffer {
    Test(int mark, int pos, int lim, int cap, byte[] hb, int offset) {
        super(mark, pos, lim, cap, hb, offset);
    }

    @Override
    public ByteBuffer slice() {
        return null;
    }

    ...
}   

It compiles in Java 9 and Java 10 as well, but only when using --patch-module when compiling:

javac --patch-module java.base=. java/nio/Test.java

My question is: How (and why) does this compile?

1

There are 1 best solutions below

0
On BEST ANSWER

Are packages (that share a name) combined during compliation?

Not exactly. A package name uniquely identifies a package. There is only one for each name.

But the Java sources for the members of a package don't have to all reside in the same source tree or be compiled at the same time. The Java compiler will accept your classes' declaration of any valid package name, and accept your classes as being in the package they say they are in.

On the other hand, that does not mean you can use classes that you declare to be in a java.* or javax.* package in any given JVM. Standard JVMs will refuse to load classes belonging to those packages from any source external to the JVM. You can build such classes but you cannot use them. You can protect your own packages in much the same way, through a mechanism called "package sealing".

On the third hand, with unsealed packages, you can indeed load package members from multiple distinct sources.