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


98

我现在正在与其他人一起在grails项目中工作。我必须编写一些Java类。但是我需要访问使用groovy创建的可搜索对象。看来,该对象必须放在默认包中。

我的问题是:有没有办法从命名包中的Java类访问默认包中的此对象?

Answers:


129

您不能使用命名包中默认包中的类。
从技术上就可以了,如图Sharique阿卜杜拉的回答通过反射API,但是从无名命名空间的类是不在范围内进口申报

在J2SE 1.4之前,您可以使用以下语法从默认包中导入类:

import Unfinished;

这是不再允许。因此,要从打包的类中访问默认的包类,需要将默认的包类移动到自己的包中。

如果您可以访问groovy生成的源,则需要进行一些后期处理,以将文件移动到专用包中并在其开始处添加此“ package”指令。


2014年更新:针对JDK7和JDK8的bug 6975015描述了甚至更严格的禁止从未命名包中导入的规定。

TypeName必须是类的类型,接口类型,枚举类型,或注释类型的规范名称。
该类型必须是命名包的成员,或者是其最外面的词法包围类型是命名包的成员的类型的成员,否则会发生编译时错误


安德烈亚斯指出的评论

“为什么[默认程序包]首先出现?设计错误?”

不,这是故意的。
JLS 7.4.2。未命名的软件包说:“ Java SE平台提供的未命名软件包主要是为了在开发小型或临时应用程序或刚开始开发时提供方便。”


7
正如我之前向其他人解释的那样,默认软件包是Java世界中的二等公民。只是不要那样做。:-)
克里斯·杰斯特·杨

1
似乎我必须学习Groovy(在一个非常受时间限制的项目中)或使用默认包中的代码。:-(
Mnementh

11
@ ChrisJester-Young如果是这样,为什么它首先出现在其中?设计错误?
Pacerier,2011年

为什么不推荐使用?
Suzan Cioc 2014年

@SuzanCioc是什么意思:“为什么在J2SE1.4之后,您不能再访问默认软件包?”
VonC 2014年

61

其实可以。

使用反射API,您可以访问到目前为止的任何类。至少我能够:)

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

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

对于Scala,以下代码有效:val bar = "hi"; val fooClass = Class.forName("FooClass"); val fooMethod = fooClass.getMethod("foo", classOf[Array[String]]); val fooReturned = fooMethod.invoke(fooClass.newInstance(), Array(bar));
2012年

2
好的答案,+ 1。但是,由于问题很棘手,所以您可以使用鸭子打字(我猜想像是胶带录音)...Class.forName("FooBar").newInstance().fooMethod("I did it")
比尔·K

7

使用jarjar通过以下规则重新打包jar文件:

rule * <target package name>.@1

源jar文件的默认软件包中的所有类都将移至目标软件包,因此可以访问。


4
一个如何使用jarjar的演示会很棒
BiGGZ

@BiGGZ:请参见jarjar github 存储库上的README.md文件,以了解如何将jarjar与ant,gradle或命令行一起使用。
Lucidiot

3

您可以在Groovy代码中使用包,然后一切正常。

这可能意味着对代码进行了较小的重组,grails-app乍一看有点痛苦,但是在大型grails项目中,将事情组织在包中是有意义的。我们使用Java标准包命名约定com.foo.<app>.<package>

正如您所发现的,将所有内容都放在默认程序包中成为集成的障碍。

控制器似乎是拒绝将其放置在Java包中的一种Grails工件(或工件)。可能我还没有想到Convention。;-)


0

只是为了完成这个想法:

您可以默认包内部访问驻留在命名包中的对象。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.