如何访问默认包中的 java 类?

我现在和其他人一起做一个圣杯项目。我得写一些 Java 类。但我需要访问用 groovy 创建的可搜索对象。看起来,这个对象必须放在 default-package 中。

我的问题是: 有没有一种方法可以从命名包中的 Java 类访问默认包中的这个对象?

82671 次浏览

You can’t use classes in the default package from a named package.
(Technically you can, as shown in Sharique Abdullah's answer through reflection API, but classes from the unnamed namespace are not in scope in an import declaration)

Prior to J2SE 1.4 you could import classes from the default package using a syntax like this:

import Unfinished;

That's no longer allowed. So to access a default package class from within a packaged class requires moving the default package class into a package of its own.

If you have access to the source generated by groovy, some post-processing is needed to move the file into a dedicated package and add this "package" directive at its beginning.


Update 2014: bug 6975015, for JDK7 and JDK8, describe an even stricter prohibition against import from unnamed package.

The TypeName must be the canonical name of a class type, interface type, enum type, or annotation type.
The type must be either a member of a named package, or a member of a type whose outermost lexically enclosing type is a member of a named package, or a compile-time error occurs.


Andreas points out in the comments:

"why is [the default package] there in the first place? design error?"

No, it's deliberate.
JLS 7.4.2. Unnamed Packages says: "Unnamed packages are provided by the Java SE platform principally for convenience when developing small or temporary applications or when just beginning development".

You can use packages in the Groovy code, and things will work just fine.

It may mean a minor reorganization of code under grails-app and a little bit of a pain at first, but on a large grails project, it just make sense to organize things in packages. We use the Java standard package naming convention com.foo.<app>.<package>.

Having everything in the default package becomes a hindrance to integration, as you're finding.

Controllers seem to be the one Grails artifact (or artefact) that resists being put in a Java package. Probably I just haven't figured out the Convention for that yet. ;-)

In fact, you can.

Using reflections API you can access any class so far. At least I was able to :)

Class fooClass = Class.forName("FooBar");
Method fooMethod = fooClass.getMethod("fooMethod", String.class);


String fooReturned = (String)fooMethod.invoke(fooClass.newInstance(), "I did it");

Use jarjar to repackage the jar file with the following rule:

rule * <target package name>.@1

All classes in the default package of the source jar file will move to the target package, thus are able to access.

just to complete the idea:

From inside default-package you can access objects resided in named packages.